mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-28 01:29:05 +01:00
Major update of the et2_widget internal structure. The following changes were made:
- All attributes of the widgets are now parsed from XML before the widget itself is created. These attributes plus all default values are then added to an associative array. The associative array is passed as second parameter to the init function of et2_widget, but is also available as this.options *after* the constructor of the et2_widget baseclass has been called. The et2_widget constructor also calls a function parseArrayMgrAttrs(_attrs) - in this function widget implementations can read the values from e.g. the content and validation_errors array and merge it into the given _attrs associative array. After the complete internal widgettree is completely loaded and created the "loadingFinished" function gets called and invokes all given setter functions. After that it "glues" the DOM tree together. This should also (I didn't measure it) be a bit faster than before, when the DOM-Tree was created on the fly. Please have a look at the changes of the et2_textbox widget to see how this affects writing widgets. Note: The "id" property is copied to the object scope on the top of the et2_widget constructor. - When widgets are cloned the "options" array gets passed along to the newly created widget. This means that changes made on the widgets during runtime are not automatically copied to the clone - as this didn't happen anyhow it is not a really disadvantage. On the other side there should be no difference between widgets directly inside the "overlay" xet tag and widgets which are inside instanciated templates. - The selbox widget doesn't work anymore - it relied on the loadAttributes function which isn't available anymore. et2_selbox should use the parseArrayMgrAttrs function to access - I've commented out some of the "validator"-code in etemplate2.js as it created some error messages when destroying the widget tree.
This commit is contained in:
parent
a572007f1c
commit
5af5594f60
@ -52,6 +52,18 @@ var et2_DOMWidget = et2_widget.extend(et2_IDOMNode, {
|
||||
"type": "boolean",
|
||||
"description": "Defines whether this widget is visible.",
|
||||
"default": false
|
||||
},
|
||||
"width": {
|
||||
"name": "Width",
|
||||
"type": "dimension",
|
||||
"default": et2_no_init,
|
||||
"description": "Width of the element in pixels, percentage or 'auto'"
|
||||
},
|
||||
"height": {
|
||||
"name": "Height",
|
||||
"type": "dimension",
|
||||
"default": et2_no_init,
|
||||
"description": "Height of the element in pixels, percentage or 'auto'"
|
||||
}
|
||||
},
|
||||
|
||||
@ -59,7 +71,10 @@ var et2_DOMWidget = et2_widget.extend(et2_IDOMNode, {
|
||||
* When the DOMWidget is initialized, it grabs the DOM-Node of the parent
|
||||
* object (if available) and passes it to its own "createDOMNode" function
|
||||
*/
|
||||
init: function(_parent, _type) {
|
||||
init: function() {
|
||||
// Call the inherited constructor
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
this.parentNode = null;
|
||||
|
||||
this._attachSet = {
|
||||
@ -67,10 +82,7 @@ var et2_DOMWidget = et2_widget.extend(et2_IDOMNode, {
|
||||
"parent": null
|
||||
};
|
||||
|
||||
this.disabled = false;
|
||||
|
||||
// Call the inherited constructor
|
||||
this._super.apply(this, arguments);
|
||||
this._disabled = false;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -87,14 +99,16 @@ var et2_DOMWidget = et2_widget.extend(et2_IDOMNode, {
|
||||
},
|
||||
|
||||
/**
|
||||
* Automatically tries to attach this node to the parent widget.
|
||||
* Attaches the container node of this widget to the DOM-Tree
|
||||
*/
|
||||
onSetParent: function() {
|
||||
doLoadingFinished: function() {
|
||||
// Check whether the parent implements the et2_IDOMNode interface. If
|
||||
// yes, grab the DOM node and create our own.
|
||||
if (this._parent && this._parent.implements(et2_IDOMNode)) {
|
||||
this.setParentDOMNode(this._parent.getDOMNode(this));
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -192,7 +206,7 @@ var et2_DOMWidget = et2_widget.extend(et2_IDOMNode, {
|
||||
},
|
||||
|
||||
set_disabled: function(_value) {
|
||||
var node = this.getDOMNode();
|
||||
var node = this.getDOMNode(this);
|
||||
if (node)
|
||||
{
|
||||
this.disabled = _value;
|
||||
@ -206,8 +220,27 @@ var et2_DOMWidget = et2_widget.extend(et2_IDOMNode, {
|
||||
$j(node).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
set_width: function(_value) {
|
||||
this.width = _value;
|
||||
|
||||
var node = this.getDOMNode(this);
|
||||
if (node)
|
||||
{
|
||||
$j(node).css("width", _value);
|
||||
}
|
||||
},
|
||||
|
||||
set_height: function(_value) {
|
||||
this.height = _value;
|
||||
|
||||
var node = this.getDOMNode(this);
|
||||
if (node)
|
||||
{
|
||||
$j(node).css("height", _value);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
@ -128,16 +128,8 @@ var et2_baseWidget = et2_DOMWidget.extend(et2_IAligned, {
|
||||
}
|
||||
},
|
||||
|
||||
// XXX I really don't like this - I think I'll move attaching the DOM-Nodes
|
||||
// to the loadFinished function - this should also be faster...
|
||||
set_align: function(_value) {
|
||||
if (_value != this.align)
|
||||
{
|
||||
this.align = _value;
|
||||
|
||||
// Reattach this node to the DOM
|
||||
this.onSetParent();
|
||||
}
|
||||
this.align = _value;
|
||||
},
|
||||
|
||||
get_align: function(_value) {
|
||||
@ -171,32 +163,49 @@ var et2_placeholder = et2_baseWidget.extend({
|
||||
// values of this object
|
||||
this.attrNodes = {};
|
||||
|
||||
this.visible = false;
|
||||
|
||||
// Create the placeholder div
|
||||
this.placeDiv = $j(document.createElement("span"))
|
||||
.addClass("et2_placeholder");
|
||||
|
||||
var headerNode = $j(document.createElement("span"))
|
||||
.text(this.type)
|
||||
.text(this._type)
|
||||
.addClass("et2_caption")
|
||||
.appendTo(this.placeDiv);
|
||||
|
||||
this.setDOMNode(this.placeDiv[0]);
|
||||
},
|
||||
var attrsCntr = $j(document.createElement("span"))
|
||||
.appendTo(this.placeDiv)
|
||||
.hide();
|
||||
|
||||
loadAttributes: function(_attrs) {
|
||||
for (var i = 0; i < _attrs.length; i++)
|
||||
{
|
||||
var attr = _attrs[i];
|
||||
|
||||
if (typeof this.attrNodes[attr.name] == "undefined")
|
||||
headerNode.click(this, function(e) {
|
||||
e.data.visible = !e.data.visible;
|
||||
if (e.data.visible)
|
||||
{
|
||||
this.attrNodes[attr.name] = $j(document.createElement("span"))
|
||||
.addClass("et2_attr");
|
||||
this.placeDiv.append(this.attrNodes[attr.name]);
|
||||
attrsCntr.show();
|
||||
}
|
||||
else
|
||||
{
|
||||
attrsCntr.hide();
|
||||
}
|
||||
});
|
||||
|
||||
this.attrNodes[attr.name].text(attr.name + "=" + attr.value);
|
||||
for (var key in this.options)
|
||||
{
|
||||
if (typeof this.options[key] != "undefined")
|
||||
{
|
||||
if (typeof this.attrNodes[key] == "undefined")
|
||||
{
|
||||
this.attrNodes[key] = $j(document.createElement("span"))
|
||||
.addClass("et2_attr");
|
||||
attrsCntr.append(this.attrNodes[key]);
|
||||
}
|
||||
|
||||
this.attrNodes[key].text(key + "=" + this.options[key]);
|
||||
}
|
||||
}
|
||||
|
||||
this.setDOMNode(this.placeDiv[0]);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -22,21 +22,16 @@
|
||||
*/
|
||||
var et2_box = et2_baseWidget.extend({
|
||||
|
||||
init: function(_parent, _type) {
|
||||
createNamespace: true,
|
||||
|
||||
init: function() {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
this.div = $j(document.createElement("div"))
|
||||
.addClass("et2_" + _type)
|
||||
.addClass("et2_" + this._type)
|
||||
.addClass("et2_box_widget");
|
||||
|
||||
this.setDOMNode(this.div[0]);
|
||||
},
|
||||
|
||||
set_id: function(_value) {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
// Check whether a namespace exists for this element
|
||||
this.checkCreateNamespace();
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -109,9 +109,6 @@ var et2_checkbox_ro = et2_checkbox.extend({
|
||||
}
|
||||
},
|
||||
|
||||
init: function(_parent) {
|
||||
},
|
||||
|
||||
init: function() {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
|
@ -71,7 +71,7 @@ function et2_debug(_level)
|
||||
/**
|
||||
* Array with all types supported by the et2_checkType function.
|
||||
*/
|
||||
var et2_validTypes = ["boolean", "string", "float", "integer", "any", "js"];
|
||||
var et2_validTypes = ["boolean", "string", "float", "integer", "any", "js", "dimension"];
|
||||
|
||||
/**
|
||||
* Object whith default values for the above types. Do not specify array or
|
||||
@ -84,7 +84,8 @@ var et2_typeDefaults = {
|
||||
"js": null,
|
||||
"float": 0.0,
|
||||
"integer": 0,
|
||||
"any": null
|
||||
"any": null,
|
||||
"dimension": "auto"
|
||||
};
|
||||
|
||||
function et2_evalBool(_val)
|
||||
@ -144,7 +145,7 @@ function et2_checkType(_val, _type, _attr)
|
||||
if (_type == "js")
|
||||
{
|
||||
// Handle the default case
|
||||
if (_val === null)
|
||||
if (_val === null || _val instanceof Function)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@ -204,6 +205,32 @@ function et2_checkType(_val, _type, _attr)
|
||||
return _err();
|
||||
}
|
||||
|
||||
// Parse the given dimension value
|
||||
if (_type == "dimension")
|
||||
{
|
||||
// Case 1: The value is "auto"
|
||||
if (_val == "auto")
|
||||
{
|
||||
return _val;
|
||||
}
|
||||
|
||||
// Case 2: The value is simply a number, attach "px"
|
||||
if (!isNaN(_val))
|
||||
{
|
||||
return parseFloat(_val) + "px";
|
||||
}
|
||||
|
||||
// Case 3: The value is already a valid css pixel value or a percentage
|
||||
if (typeof _val == "string" &&
|
||||
((_val.indexOf("px") == _val.length - 2 && !isNaN(_val.split("px")[0])) ||
|
||||
(_val.indexOf("%") == _val.length - 1 && !isNaN(_val.split("%")[0]))))
|
||||
{
|
||||
return _val;
|
||||
}
|
||||
|
||||
return _err();
|
||||
}
|
||||
|
||||
// We should never come here
|
||||
throw("Invalid type identifier supplied.");
|
||||
}
|
||||
|
@ -402,9 +402,6 @@ var et2_grid = et2_DOMWidget.extend({
|
||||
"widget": cell.widget
|
||||
});
|
||||
|
||||
// Trigger the "onSetParent" event of the widget
|
||||
cell.widget.onSetParent();
|
||||
|
||||
// Set the span values of the cell
|
||||
var cs = (x == w - 1) ? w - x : Math.min(w - x, cell.colSpan);
|
||||
var rs = (y == h - 1) ? h - y : Math.min(h - y, cell.rowSpan);
|
||||
|
@ -22,7 +22,11 @@
|
||||
*/
|
||||
var et2_hbox = et2_baseWidget.extend({
|
||||
|
||||
init: function(_parent, _type) {
|
||||
createNamespace: true,
|
||||
|
||||
init: function(_parent) {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
this.alignData = {
|
||||
"hasAlign": false,
|
||||
"hasLeft": false,
|
||||
@ -34,10 +38,8 @@ var et2_hbox = et2_baseWidget.extend({
|
||||
this.leftDiv = null;
|
||||
this.rightDiv = null;
|
||||
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
this.div = $j(document.createElement("div"))
|
||||
.addClass("et2_" + _type)
|
||||
.addClass("et2_" + this._type)
|
||||
.addClass("et2_box_widget");
|
||||
|
||||
this.setDOMNode(this.div[0]);
|
||||
@ -159,15 +161,7 @@ var et2_hbox = et2_baseWidget.extend({
|
||||
|
||||
// Normally simply return the hbox-div
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
set_id: function(_value) {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
// Check whether a namespace exists for this element
|
||||
this.checkCreateNamespace();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
et2_register_widget(et2_hbox, ["hbox"]);
|
||||
|
@ -261,12 +261,6 @@
|
||||
{
|
||||
this.init.apply(this, arguments);
|
||||
}
|
||||
|
||||
// Initialize the attributes
|
||||
if (typeof this._attrsInitialized == "undefined")
|
||||
{
|
||||
this.initAttributes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -353,23 +347,67 @@
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* generateAttributeSet sanitizes the given associative array of attributes
|
||||
* (by passing each entry to "et2_checkType" and checking for existance of
|
||||
* the attribute) and adds the default values to the associative array.
|
||||
*
|
||||
* @param _attrs is the associative array containing the attributes.
|
||||
*/
|
||||
Class.prototype.generateAttributeSet = function(_attrs) {
|
||||
|
||||
// Sanity check and validation
|
||||
for (var key in _attrs)
|
||||
{
|
||||
if (typeof this.attributes[key] != "undefined")
|
||||
{
|
||||
if (!this.attributes[key].ignore)
|
||||
{
|
||||
_attrs[key] = et2_checkType(_attrs[key], this.attributes[key].type,
|
||||
key);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Key does not exist - delete it and issue a warning
|
||||
delete(_attrs[key]);
|
||||
et2_debug("warn", this, "Attribute '" + key +
|
||||
"' does not exist!");
|
||||
}
|
||||
}
|
||||
|
||||
// Include default values or already set values for this attribute
|
||||
for (var key in this.attributes)
|
||||
{
|
||||
if (typeof _attrs[key] == "undefined")
|
||||
{
|
||||
var _default = this.attributes[key]["default"];
|
||||
if (_default == et2_no_init)
|
||||
{
|
||||
_default = undefined;
|
||||
}
|
||||
|
||||
_attrs[key] = _default;
|
||||
}
|
||||
}
|
||||
|
||||
return _attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
Class.prototype.initAttributes = function() {
|
||||
for (var key in this.attributes)
|
||||
Class.prototype.initAttributes = function(_attrs) {
|
||||
for (var key in _attrs)
|
||||
{
|
||||
if (!this.attributes[key].ignore && this.attributes[key]["default"] !== et2_no_init)
|
||||
if (!this.attributes[key].ignore && !(_attrs[key] == undefined))
|
||||
{
|
||||
this.setAttribute(key, this.attributes[key]["default"],
|
||||
false);
|
||||
this.setAttribute(key, _attrs[key], false);
|
||||
}
|
||||
}
|
||||
|
||||
this._attrsInitialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,6 +71,7 @@ var et2_inputWidget = et2_valueWidget.extend(et2_IInput, {
|
||||
$j(this.getInputNode()).attr("novalidate","novalidate"); // Stop browser from getting involved
|
||||
$j(this.getInputNode()).validator();
|
||||
},
|
||||
|
||||
detatchFromDOM: function() {
|
||||
if(this.getInputNode()) {
|
||||
$j(this.getInputNode()).data("validator").destroy();
|
||||
|
@ -134,18 +134,13 @@ var et2_tabbox = et2_DOMWidget.extend({
|
||||
|
||||
entry.contentDiv = $j(document.createElement("div"))
|
||||
.addClass("et2_tabcntr")
|
||||
.hide()
|
||||
.appendTo(this.tabContainer);
|
||||
|
||||
// Let the widget appear on its corresponding page
|
||||
entry.widget.onSetParent();
|
||||
}
|
||||
|
||||
this.setActiveTab(0);
|
||||
},
|
||||
|
||||
setActiveTab: function(_idx) {
|
||||
console.log(_idx);
|
||||
// Remove the "active" flag from all tabs-flags
|
||||
$j(".et2_tabflag", this.flagContainer).removeClass("active");
|
||||
|
||||
@ -175,6 +170,12 @@ var et2_tabbox = et2_DOMWidget.extend({
|
||||
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
set_height: function(_value) {
|
||||
this.height = _value;
|
||||
|
||||
this.tabContainer.css("height", _value);
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -44,26 +44,60 @@ var et2_template = et2_DOMWidget.extend({
|
||||
}
|
||||
},
|
||||
|
||||
createNamespace: true,
|
||||
|
||||
/**
|
||||
* Initializes this template widget as a simple container.
|
||||
*/
|
||||
init: function(_parent) {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
this.proxiedTemplate = null;
|
||||
this.isProxied = false;
|
||||
|
||||
this.div = document.createElement("div");
|
||||
this.id = "";
|
||||
|
||||
this._super.apply(this, arguments);
|
||||
if (this.id != "")
|
||||
{
|
||||
this.createProxy();
|
||||
}
|
||||
},
|
||||
|
||||
createProxy: function() {
|
||||
// Check whether a template with the given name already exists and
|
||||
// is not a proxy.
|
||||
var tmpl = this.getRoot().getWidgetById(this.id);
|
||||
if (tmpl instanceof et2_template && tmpl.proxiedTemplate == null &&
|
||||
tmpl != this)
|
||||
{
|
||||
// Detatch the proxied template from the DOM to and set its
|
||||
// isProxied property to true
|
||||
tmpl.makeProxied();
|
||||
|
||||
// Do not copy the id when cloning as this leads to infinit
|
||||
// recursion
|
||||
tmpl.options.id = "";
|
||||
|
||||
// Create a clone of the template and add it as child of this
|
||||
// template (done by passing "this" to the clone function)
|
||||
this.proxiedTemplate = tmpl.clone(this);
|
||||
|
||||
// Reset the "ignore" flag and manually copy the id
|
||||
tmpl.options.id = this.id;
|
||||
this.proxiedTemplate.id = tmpl.id;
|
||||
this.proxiedTemplate.isProxied = true;
|
||||
|
||||
// Disallow adding any new node to this template
|
||||
this.supportedWidgetClasses = [];
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* If the parent node is changed, either the DOM-Node of the proxied template
|
||||
* or the DOM-Node of this template is connected to the parent DOM-Node.
|
||||
*/
|
||||
onSetParent: function() {
|
||||
// Check whether the parent implements the et2_IDOMNode interface. If
|
||||
// yes, grab the DOM node and create our own.
|
||||
doLoadingFinished: function() {
|
||||
// Check whether the parent implements the et2_IDOMNode interface.
|
||||
if (this._parent && this._parent.implements(et2_IDOMNode)) {
|
||||
var parentNode = this._parent.getDOMNode(this);
|
||||
|
||||
@ -72,6 +106,8 @@ var et2_template = et2_DOMWidget.extend({
|
||||
if (this.proxiedTemplate)
|
||||
{
|
||||
this.proxiedTemplate.setParentDOMNode(parentNode);
|
||||
this.proxiedTemplate.loadingFinished();
|
||||
return false;
|
||||
}
|
||||
else if (!this.isProxied)
|
||||
{
|
||||
@ -79,6 +115,8 @@ var et2_template = et2_DOMWidget.extend({
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
makeProxied: function() {
|
||||
@ -92,59 +130,7 @@ var et2_template = et2_DOMWidget.extend({
|
||||
this.isProxied = true;
|
||||
},
|
||||
|
||||
set_id: function(_value) {
|
||||
if (_value != this.id)
|
||||
{
|
||||
// Check whether a template with the given name already exists and
|
||||
// is not a proxy.
|
||||
var tmpl = this.getRoot().getWidgetById(_value);
|
||||
if (tmpl instanceof et2_template && tmpl.proxiedTemplate == null &&
|
||||
tmpl != this)
|
||||
{
|
||||
// Check whether we still have a proxied template, if yes,
|
||||
// destroy it
|
||||
if (this.proxiedTemplate != null)
|
||||
{
|
||||
this.proxiedTemplate.destroy();
|
||||
this.proxiedTemplate = null;
|
||||
}
|
||||
|
||||
// This element does not have a node in the tree
|
||||
this.detatchFromDOM();
|
||||
|
||||
// Detatch the proxied template from the DOM to and set its
|
||||
// isProxied property to true
|
||||
tmpl.makeProxied();
|
||||
|
||||
// Do not copy the id when cloning as this leads to infinit
|
||||
// recursion
|
||||
tmpl.attributes["id"].ignore = true;
|
||||
|
||||
// Create a clone of the template and add it as child of this
|
||||
// template (done by passing "this" to the clone function)
|
||||
this.proxiedTemplate = tmpl.clone(this);
|
||||
|
||||
// Reset the "ignore" flag and manually copy the id
|
||||
tmpl.attributes["id"].ignore = false;
|
||||
this.proxiedTemplate.id = tmpl.id;
|
||||
|
||||
// Disallow adding any new node to this template
|
||||
this.supportedWidgetClasses = [];
|
||||
|
||||
// Call the parent change event function
|
||||
this.onSetParent();
|
||||
}
|
||||
else
|
||||
{
|
||||
this._super(_value);
|
||||
|
||||
// Check whether a namespace exists for this element
|
||||
this.checkCreateNamespace();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
getDOMNode: function(_fromProxy) {
|
||||
getDOMNode: function() {
|
||||
return this.div;
|
||||
},
|
||||
|
||||
|
@ -41,13 +41,13 @@ var et2_textbox = et2_inputWidget.extend({
|
||||
"rows": {
|
||||
"name": "Rows",
|
||||
"type": "integer",
|
||||
"default": et2_no_init,
|
||||
"default": 1,
|
||||
"description": "Multiline field height - better to use CSS"
|
||||
},
|
||||
"cols": {
|
||||
"name": "Size",
|
||||
"type": "integer",
|
||||
"default": et2_no_init,
|
||||
"default": 1,
|
||||
"description": "Multiline field width - better to use CSS"
|
||||
},
|
||||
},
|
||||
@ -56,16 +56,16 @@ var et2_textbox = et2_inputWidget.extend({
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
this.input = null;
|
||||
this.id = "";
|
||||
|
||||
this.createInputWidget();
|
||||
|
||||
},
|
||||
|
||||
createInputWidget: function() {
|
||||
if (this.multiline)
|
||||
if (this.options.multiline || this.options.rows > 1 || this.options.cols > 1)
|
||||
{
|
||||
this.input = $j(document.createElement("textarea"));
|
||||
this.input = $j(document.createElement("textarea"))
|
||||
.attr("rows", this.options.rows)
|
||||
.attr("cols", this.options.cols);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -80,44 +80,6 @@ var et2_textbox = et2_inputWidget.extend({
|
||||
this.setDOMNode(this.input[0]);
|
||||
},
|
||||
|
||||
set_multiline: function(_value) {
|
||||
if (_value != this.multiline)
|
||||
{
|
||||
this.multiline = _value;
|
||||
|
||||
this.createInputWidget();
|
||||
|
||||
// Write all settings again
|
||||
this.update();
|
||||
}
|
||||
},
|
||||
|
||||
set_rows: function(_value) {
|
||||
if (_value != this.rows)
|
||||
{
|
||||
this.rows = _value;
|
||||
if(this.rows > 1)
|
||||
{
|
||||
this.set_multiline(true);
|
||||
this.input.attr("rows", this.rows);
|
||||
} else {
|
||||
this.set_multiline(false);
|
||||
}
|
||||
}
|
||||
},
|
||||
set_cols: function(_value) {
|
||||
if (_value != this.cols)
|
||||
{
|
||||
this.cols = _value;
|
||||
if(this.cols > 1)
|
||||
{
|
||||
this.set_multiline(true);
|
||||
this.input.attr("cols", this.cols);
|
||||
} else {
|
||||
this.set_multiline(false);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Set input widget size
|
||||
|
@ -33,18 +33,18 @@ var et2_valueWidget = et2_baseWidget.extend({
|
||||
}
|
||||
},
|
||||
|
||||
loadingFinished: function() {
|
||||
parseArrayMgrAttrs: function(_attrs) {
|
||||
this._super.call(this, arguments);
|
||||
|
||||
if (this.id != "")
|
||||
{
|
||||
// Set the value for this element
|
||||
var contentMgr = this.getArrayMgr("content");
|
||||
if(contentMgr != null) {
|
||||
if (contentMgr != null) {
|
||||
var val = contentMgr.getValueForID(this.id);
|
||||
if (val !== null)
|
||||
{
|
||||
this.setAttribute("value", val)
|
||||
_attrs["value"] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -89,6 +89,11 @@ var et2_widget = Class.extend({
|
||||
// attribute defines.
|
||||
legacyOptions: [],
|
||||
|
||||
/**
|
||||
* Set this variable to true if this widget can have namespaces
|
||||
*/
|
||||
createNamespace: false,
|
||||
|
||||
/**
|
||||
* The init function is the constructor of the widget. When deriving new
|
||||
* classes from the widget base class, always call this constructor unless
|
||||
@ -97,37 +102,54 @@ var et2_widget = Class.extend({
|
||||
* @param _parent is the parent object from the XML tree which contains this
|
||||
* object. The default constructor always adds the new instance to the
|
||||
* children list of the given parent object. _parent may be NULL.
|
||||
* @param _type is the node name with which the widget has been created. This
|
||||
* is usefull if a single widget class implements multiple XET-Node widgets.
|
||||
* @param _attrs is an associative array of attributes.
|
||||
*/
|
||||
init: function(_parent, _type, _readonly) {
|
||||
init: function(_parent, _attrs) {
|
||||
|
||||
if (typeof _type == "undefined")
|
||||
// Check whether all attributes are available
|
||||
if (typeof _parent == "undefined")
|
||||
{
|
||||
_type = "widget";
|
||||
_parent = null;
|
||||
}
|
||||
|
||||
this.id = "";
|
||||
if (typeof _attrs == "undefined")
|
||||
{
|
||||
_attrs = {};
|
||||
}
|
||||
|
||||
// Initialize all important parameters
|
||||
this._mgrs = {};
|
||||
this._inst = null;
|
||||
this._children = [];
|
||||
this._type = _attrs["type"];
|
||||
this.id = _attrs["id"];
|
||||
|
||||
// Copy the parent parameter and add this widget to its parent children
|
||||
// list.
|
||||
// Add this widget to the given parent widget
|
||||
this._parent = _parent;
|
||||
this.onSetParent();
|
||||
|
||||
if (_parent != null)
|
||||
{
|
||||
this._parent.addChild(this);
|
||||
}
|
||||
|
||||
this._children = [];
|
||||
this.type = _type;
|
||||
this.readonly = _readonly;
|
||||
|
||||
// The supported widget classes array defines a whitelist for all widget
|
||||
// classes or interfaces child widgets have to support.
|
||||
this.supportedWidgetClasses = [et2_widget];
|
||||
|
||||
if (_attrs["id"])
|
||||
{
|
||||
// Create a namespace for this object
|
||||
if (this.createNamespace)
|
||||
{
|
||||
this.checkCreateNamespace();
|
||||
}
|
||||
|
||||
// Add all attributes hidden in the content arrays to the attributes
|
||||
// parameter
|
||||
this.parseArrayMgrAttrs(_attrs);
|
||||
}
|
||||
|
||||
// Create a local copy of the options object
|
||||
this.options = et2_cloneObject(_attrs);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -156,7 +178,6 @@ var et2_widget = Class.extend({
|
||||
this._children = [];
|
||||
this._parent = null;
|
||||
this._mgrs = {};
|
||||
this.onSetParent();
|
||||
},
|
||||
|
||||
/**
|
||||
@ -164,7 +185,7 @@ var et2_widget = Class.extend({
|
||||
* constructor of the copied object. If the parameters are omitted, _parent
|
||||
* is defaulted to null
|
||||
*/
|
||||
clone: function(_parent, _type) {
|
||||
clone: function(_parent) {
|
||||
|
||||
// Default _parent to null
|
||||
if (typeof _parent == "undefined")
|
||||
@ -173,7 +194,7 @@ var et2_widget = Class.extend({
|
||||
}
|
||||
|
||||
// Create the copy
|
||||
var copy = new (this.constructor)(_parent, _type, this.readonly);
|
||||
var copy = new (this.constructor)(_parent, this.options);
|
||||
|
||||
// Assign this element to the copy
|
||||
copy.assign(this);
|
||||
@ -185,22 +206,7 @@ var et2_widget = Class.extend({
|
||||
// Create a clone of all child elements of the given object
|
||||
for (var i = 0; i < _obj._children.length; i++)
|
||||
{
|
||||
_obj._children[i].clone(this, _obj._children[i].type);
|
||||
}
|
||||
|
||||
// Copy all properties
|
||||
for (var key in _obj.attributes)
|
||||
{
|
||||
if (!_obj.attributes[key].ignore)
|
||||
{
|
||||
var value = _obj.getAttribute(key);
|
||||
|
||||
// Check whether the attribute is undefined
|
||||
if (typeof value != "undefined")
|
||||
{
|
||||
this.setAttribute(key, value);
|
||||
}
|
||||
}
|
||||
_obj._children[i].clone(this);
|
||||
}
|
||||
|
||||
// Copy a reference to the content array manager
|
||||
@ -214,14 +220,6 @@ var et2_widget = Class.extend({
|
||||
return this._parent;
|
||||
},
|
||||
|
||||
/**
|
||||
* The set parent event is called, whenever the parent of the widget is set.
|
||||
* Child classes can overwrite this function. Whe onSetParent is called,
|
||||
* the change of the parent has already taken place.
|
||||
*/
|
||||
onSetParent: function() {
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the list of children of this widget.
|
||||
*/
|
||||
@ -269,7 +267,7 @@ var et2_widget = Class.extend({
|
||||
}
|
||||
else
|
||||
{
|
||||
throw("_node is not supported by this widget class!");
|
||||
throw(_node, " is not supported by this widget class!");
|
||||
}
|
||||
},
|
||||
|
||||
@ -284,7 +282,6 @@ var et2_widget = Class.extend({
|
||||
{
|
||||
// This element is no longer parent of the child
|
||||
_node._parent = null;
|
||||
_node.onSetParent();
|
||||
|
||||
this._children.splice(idx, 1);
|
||||
}
|
||||
@ -375,46 +372,103 @@ var et2_widget = Class.extend({
|
||||
return false;
|
||||
},
|
||||
|
||||
createElementFromNode: function(_node, _nodeName) {
|
||||
/**
|
||||
* The parseXMLAttrs function takes an XML DOM attributes object
|
||||
* and adds the given attributes to the _target associative array. This
|
||||
* function also parses the legacyOptions.
|
||||
*
|
||||
* @param _attrsObj is the XML DOM attributes object
|
||||
* @param _target is the object to which the attributes should be written.
|
||||
*/
|
||||
parseXMLAttrs: function(_attrsObj, _target, _proto) {
|
||||
|
||||
// Check whether the type attribute exists - if yes pass it instead of
|
||||
// the nodeName
|
||||
if (_node.getAttribute("type"))
|
||||
// Check whether the attributes object is really existing, if not abort
|
||||
if (typeof _attrsObj == "undefined")
|
||||
{
|
||||
_nodeName = _node.getAttribute("type");
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof _nodeName == "undefined")
|
||||
// Iterate over the given attributes and parse them
|
||||
for (var i = 0; i < _attrsObj.length; i++)
|
||||
{
|
||||
_nodeName = _node.nodeName.toLowerCase();
|
||||
}
|
||||
var attrName = _attrsObj[i].name;
|
||||
var attrValue = _attrsObj[i].value;
|
||||
|
||||
// Get the constructor for that widget
|
||||
// Special handling for the legacy options
|
||||
if (attrName == "options")
|
||||
{
|
||||
// Parse the legacy options
|
||||
var splitted = et2_csvSplit(attrValue);
|
||||
|
||||
for (var j = 0; j < splitted.length && j < _proto.legacyOptions.length; j++)
|
||||
{
|
||||
_target[_proto.legacyOptions[j]] = splitted[j];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var mgr = this.getArrayMgr("content");
|
||||
if (mgr != null && typeof _proto.attributes[attrName] != "undefined")
|
||||
{
|
||||
var attr = _proto.attributes[attrName];
|
||||
|
||||
// If the attribute is marked as boolean, parse the
|
||||
// expression as bool expression.
|
||||
if (attr.type == "boolean")
|
||||
{
|
||||
attrValue = mgr.parseBoolExpression(attrValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
attrValue = mgr.expandName(attrValue);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the attribute
|
||||
_target[attrName] = attrValue;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
parseArrayMgrAttrs: function() {
|
||||
},
|
||||
|
||||
createElementFromNode: function(_node) {
|
||||
|
||||
// Fetch all attributes for this element from the XML node
|
||||
var attributes = {};
|
||||
|
||||
// Parse the "readonly" and "type" flag for this element here, as they
|
||||
// determine which constructor is used
|
||||
var _nodeName = attributes["type"] = _node.getAttribute("type") ?
|
||||
_node.getAttribute("type") : _node.nodeName.toLowerCase();
|
||||
var readonly = attributes["readonly"] =
|
||||
this.getArrayMgr("readonlys").isReadOnly(
|
||||
_node.getAttribute("id"), _node.getAttribute("readonly"),
|
||||
this.readonly);
|
||||
|
||||
// Get the constructor - if the widget is readonly, use the special "_ro"
|
||||
// constructor if it is available
|
||||
var constructor = typeof et2_registry[_nodeName] == "undefined" ?
|
||||
et2_placeholder : et2_registry[_nodeName];
|
||||
|
||||
// Check whether the widget is marked as readonly and whether a special
|
||||
// readonly type (suffixed with "_ro") is registered
|
||||
var mgr = this.getArrayMgr("readonlys");
|
||||
var readonly = false;
|
||||
if(mgr != null) {
|
||||
readonly = mgr.isReadOnly(
|
||||
_node.getAttribute("id"), _node.getAttribute("readonly"), this.readonly);
|
||||
}
|
||||
if (readonly && typeof et2_registry[_nodeName + "_ro"] != "undefined")
|
||||
{
|
||||
constructor = et2_registry[_nodeName + "_ro"];
|
||||
}
|
||||
|
||||
// Parse the attributes from the given XML attributes object
|
||||
this.parseXMLAttrs(_node.attributes, attributes, constructor.prototype);
|
||||
|
||||
// Do an sanity check for the attributes
|
||||
constructor.prototype.generateAttributeSet(attributes);
|
||||
|
||||
// Creates the new widget, passes this widget as an instance and
|
||||
// passes the widgetType. Then it goes on loading the XML for it.
|
||||
var widget = new constructor(this, _nodeName, readonly);
|
||||
var widget = new constructor(this, attributes);
|
||||
|
||||
// Load the widget itself from XML
|
||||
widget.loadFromXML(_node);
|
||||
|
||||
// Call the "loadFinished" function of the widget
|
||||
widget.loadingFinished();
|
||||
|
||||
return widget;
|
||||
},
|
||||
|
||||
@ -422,12 +476,6 @@ var et2_widget = Class.extend({
|
||||
* Loads the widget tree from an XML node
|
||||
*/
|
||||
loadFromXML: function(_node) {
|
||||
// Try to load the attributes of the current node
|
||||
if (_node.attributes)
|
||||
{
|
||||
this.loadAttributes(_node.attributes);
|
||||
}
|
||||
|
||||
// Load the child nodes.
|
||||
for (var i = 0; i < _node.childNodes.length; i++)
|
||||
{
|
||||
@ -453,51 +501,6 @@ var et2_widget = Class.extend({
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Loads the widget attributes from the passed DOM attributes array.
|
||||
*/
|
||||
loadAttributes: function(_attrs) {
|
||||
for (var i = 0; i < _attrs.length; i++)
|
||||
{
|
||||
// Special handling for the legacy options
|
||||
if (_attrs[i].name == "options")
|
||||
{
|
||||
// Parse the legacy options
|
||||
var splitted = et2_csvSplit(_attrs[i].value);
|
||||
|
||||
for (var j = 0; j < splitted.length && j < this.legacyOptions.length; j++)
|
||||
{
|
||||
this.setAttribute(this.legacyOptions[j], splitted[j]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var attrName = _attrs[i].name;
|
||||
var attrValue = _attrs[i].value;
|
||||
|
||||
var mgr = this.getArrayMgr("content");
|
||||
if (mgr != null && typeof this.attributes[attrName] != "undefined")
|
||||
{
|
||||
var attr = this.attributes[attrName];
|
||||
|
||||
// If the attribute is marked as boolean, parse the
|
||||
// expression as bool expression.
|
||||
if (attr.type == "boolean")
|
||||
{
|
||||
attrValue = mgr.parseBoolExpression(attrValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
attrValue = mgr.expandName(attrValue);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the attribute
|
||||
this.setAttribute(attrName, attrValue);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Called whenever textNodes are loaded from the XML tree
|
||||
*/
|
||||
@ -505,34 +508,28 @@ var et2_widget = Class.extend({
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when loading of the widget from XML node is finished. This
|
||||
* function can be used to load the data from the data arrays (content,
|
||||
* readonlys, sel_options etc.)
|
||||
* Called when loading the widget (sub-tree) is finished. First when this
|
||||
* function is called, the DOM-Tree is created. loadingFinished is
|
||||
* recursively called for all child elements. Do not directly override this
|
||||
* function but the doLoadingFinished function which is executed before
|
||||
* descending deeper into the DOM-Tree
|
||||
*/
|
||||
loadingFinished: function() {
|
||||
},
|
||||
// Call all availble setters
|
||||
this.initAttributes(this.options);
|
||||
|
||||
/**
|
||||
* Calls the setter of each property with its current value, calls the
|
||||
* 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.attributes)
|
||||
if (this.doLoadingFinished())
|
||||
{
|
||||
if (!this.attributes[key].ignore)
|
||||
// Descend recursively into the tree
|
||||
for (var i = 0; i < this._children.length; i++)
|
||||
{
|
||||
this.setAttribute(key, this.getAttribute(key));
|
||||
this._children[i].loadingFinished();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Call the update function of all children.
|
||||
for (var i = 0; i < this._children.length; i++)
|
||||
{
|
||||
this._children[i].update();
|
||||
}
|
||||
doLoadingFinished: function() {
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -20,7 +20,7 @@
|
||||
et2_description;
|
||||
et2_textbox;
|
||||
et2_number;
|
||||
et2_selectbox;
|
||||
// et2_selectbox;
|
||||
et2_checkbox;
|
||||
et2_radiobox;
|
||||
et2_styles;
|
||||
@ -64,7 +64,7 @@ etemplate2.prototype.clear = function()
|
||||
{
|
||||
if (this.widgetContainer != null)
|
||||
{
|
||||
$j(':input',this.DOMContainer).validator().data("validator").destroy();
|
||||
// $j(':input',this.DOMContainer).validator().data("validator").destroy();
|
||||
this.widgetContainer.destroy();
|
||||
this.widgetContainer = null;
|
||||
}
|
||||
@ -121,7 +121,10 @@ etemplate2.prototype.load = function(_url, _data)
|
||||
// Asynchronously load the XET file (code below is executed ahead of the
|
||||
// code in the callback function)
|
||||
et2_loadXMLFromURL(_url, function(_xmldoc) {
|
||||
// Read the XML structure
|
||||
this.widgetContainer.loadFromXML(_xmldoc);
|
||||
// Inform the widget tree that it has been successfully loaded.
|
||||
this.widgetContainer.loadingFinished();
|
||||
}, this);
|
||||
|
||||
// Clear any existing instance
|
||||
@ -152,13 +155,13 @@ etemplate2.prototype.load = function(_url, _data)
|
||||
etemplate2.prototype.submit = function()
|
||||
{
|
||||
// Validator
|
||||
var valid = true;
|
||||
/*var valid = true;
|
||||
var inputs = $j(':input',this.DOMContainer).each(function() {
|
||||
if(typeof $j(this).data("validator") == "undefined") return true;
|
||||
valid = valid && $j(this).data("validator").checkValidity();
|
||||
return true;
|
||||
});
|
||||
if(!valid) return false;
|
||||
if(!valid) return false;*/
|
||||
|
||||
// Get the form values
|
||||
var values = this.widgetContainer.getValues();
|
||||
@ -263,7 +266,7 @@ function etemplate2_handle_response(_type, _response)
|
||||
throw("Error while parsing et2_load response");
|
||||
} else if (_type == "et2_validation_error") {
|
||||
// Display validation errors
|
||||
$j(':input',this.DOMContainer).data("validator").invalidate(_response.data);
|
||||
// $j(':input',this.DOMContainer).data("validator").invalidate(_response.data);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0"?>
|
||||
<overlay>
|
||||
<tabbox>
|
||||
<tabbox width="100%">
|
||||
<tabs>
|
||||
<tab label="Test1" />
|
||||
<tab label="Test2" />
|
||||
@ -8,10 +8,18 @@
|
||||
<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"/>
|
||||
<vbox>
|
||||
<label value="This is the content of tab 1"/>
|
||||
<label value="This is the content of tab 1"/>
|
||||
<label value="This is the content of tab 1"/>
|
||||
<label value="This is the content of tab 1"/>
|
||||
<label value="This is the content of tab 1"/>
|
||||
<label value="This is the content of tab 1"/>
|
||||
<label value="This is the content of tab 1"/>
|
||||
</vbox>
|
||||
</tabpanels>
|
||||
</tabbox>
|
||||
</overlay>
|
||||
|
@ -86,6 +86,7 @@ div.et2_hbox_right {
|
||||
margin: 0 0 5px 0;
|
||||
font-weight: bold;
|
||||
color: #2E2E2E;
|
||||
cursor: pointer;
|
||||
text-shadow: rgba(255, 255, 255, 0.5) 0 1px 0;
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
<script src="../et2_hbox.js"></script>
|
||||
<script src="../et2_textbox.js"></script>
|
||||
<script src="../et2_number.js"></script>
|
||||
<script src="../et2_selectbox.js"></script>
|
||||
<!-- <script src="../et2_selectbox.js"></script>-->
|
||||
<script src="../et2_checkbox.js"></script>
|
||||
<script src="../et2_radiobox.js"></script>
|
||||
<script src="../et2_styles.js"></script>
|
||||
|
Loading…
Reference in New Issue
Block a user