forked from extern/egroupware
- Checked browser compatibility, tested with IE8, Chrome, Opera, FF3.6
- Added indexOf function for IE compatiblity - this and some other code is redundant to that in egw_action_common.js - Probably this code should be merged into jsapi and jsapi.js should be cleaned up and splitted into multiple files - Implemented template widget - Implemented dummy implementation of description widget - Improved et2_placeholder - it now shows all properties set for that placeholder - Improved and extended test page - Improved interface system in et2_inheritance.js - each object derrived from Class now has a instanceOf function which checks, whether the object is either an instance of the given class or implements the given interface (same behaviour as instanceOf in Java) - Widgets can now define which other widget classes are allowed inside of them
This commit is contained in:
parent
9b7819977d
commit
8b2dae28f7
@ -31,3 +31,19 @@ function et2_debug(_level, _msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IE Fix for array.indexOf
|
||||||
|
*/
|
||||||
|
if (typeof Array.prototype.indexOf == "undefined")
|
||||||
|
{
|
||||||
|
Array.prototype.indexOf = function(_elem) {
|
||||||
|
for (var i = 0; i < this.length; i++)
|
||||||
|
{
|
||||||
|
if (this[i] === _elem)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
47
etemplate/js/et2_description.js
Normal file
47
etemplate/js/et2_description.js
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/**
|
||||||
|
* eGroupWare eTemplate2 - JS Template 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$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*egw:uses
|
||||||
|
jquery.jquery;
|
||||||
|
et2_widget;
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class which implements the "description" XET-Tag
|
||||||
|
*/
|
||||||
|
et2_description = et2_DOMWidget.extend({
|
||||||
|
|
||||||
|
init: function(_parent) {
|
||||||
|
this.span = $j(document.createElement("span"));
|
||||||
|
|
||||||
|
this._super.apply(this, arguments);
|
||||||
|
this.value = "";
|
||||||
|
},
|
||||||
|
|
||||||
|
set_value: function(_value) {
|
||||||
|
if (_value != this.value)
|
||||||
|
{
|
||||||
|
this.value = _value;
|
||||||
|
|
||||||
|
this.span.text(_value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getDOMNode: function() {
|
||||||
|
return this.span[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
et2_register_widget(et2_description, ["description"]);
|
||||||
|
|
||||||
|
|
@ -21,11 +21,11 @@
|
|||||||
* where "interfaces" is a single interface or an array of interfaces and
|
* where "interfaces" is a single interface or an array of interfaces and
|
||||||
* functions an object containing the functions the class implements.
|
* functions an object containing the functions the class implements.
|
||||||
*
|
*
|
||||||
* A single interface is also a simple object defining (empty) functions. Example:
|
* An interface has to be created in the following way:
|
||||||
*
|
*
|
||||||
* IBreathingObject = {
|
* IBreathingObject = new Interface({
|
||||||
* breath: function() {}
|
* breath: function() {}
|
||||||
* }
|
* });
|
||||||
*
|
*
|
||||||
* Human = Class.extend(IBreathingObject, {
|
* Human = Class.extend(IBreathingObject, {
|
||||||
* walk: function() {
|
* walk: function() {
|
||||||
@ -72,6 +72,15 @@
|
|||||||
// check whether a
|
// check whether a
|
||||||
var fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
|
var fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
|
||||||
|
|
||||||
|
// Base "Class" for interfaces - needed to check whether an object is an
|
||||||
|
// interface
|
||||||
|
this.Interface = function(fncts) {
|
||||||
|
for (var key in fncts)
|
||||||
|
{
|
||||||
|
this[key] = fncts[key];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The addInterfaceStuff function adds all interface functions the class has
|
* The addInterfaceStuff function adds all interface functions the class has
|
||||||
* to implement to the class prototype.
|
* to implement to the class prototype.
|
||||||
@ -84,15 +93,23 @@
|
|||||||
|
|
||||||
prototype["_ifacefuncs"] = [];
|
prototype["_ifacefuncs"] = [];
|
||||||
|
|
||||||
for (var i in interfaces)
|
for (var i = 0; i < interfaces.length; i++)
|
||||||
{
|
{
|
||||||
for (var key in interfaces[i])
|
var iface = interfaces[i];
|
||||||
|
if (iface instanceof Interface)
|
||||||
|
{
|
||||||
|
for (var key in iface)
|
||||||
{
|
{
|
||||||
prototype["_ifacefuncs"].push(key);
|
prototype["_ifacefuncs"].push(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw("Interfaces must be instanceof Interface!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (var i in ifaces)
|
for (var i = 0; i < ifaces.length; i++)
|
||||||
{
|
{
|
||||||
prototype["_ifacefuncs"].push(ifaces[i]);
|
prototype["_ifacefuncs"].push(ifaces[i]);
|
||||||
}
|
}
|
||||||
@ -109,7 +126,21 @@
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The instanceOf function can be used to check for both - classes and
|
||||||
|
// interfaces. Please don't change the case of this function as this
|
||||||
|
// affects IE and Opera support.
|
||||||
|
prototype["instanceOf"] = function(_obj) {
|
||||||
|
if (_obj instanceof Interface)
|
||||||
|
{
|
||||||
|
return this.implements(_obj);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return this instanceof _obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// The base Class implementation (does nothing)
|
// The base Class implementation (does nothing)
|
||||||
this.Class = function(){};
|
this.Class = function(){};
|
||||||
@ -179,13 +210,8 @@
|
|||||||
// All construction is actually done in the init method
|
// All construction is actually done in the init method
|
||||||
if (!initializing)
|
if (!initializing)
|
||||||
{
|
{
|
||||||
if (this.init)
|
|
||||||
{
|
|
||||||
this.init.apply(this, arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check whether the object implements all interface functions
|
// Check whether the object implements all interface functions
|
||||||
for (var i in this._ifacefuncs)
|
for (var i = 0; i < this._ifacefuncs.length; i++)
|
||||||
{
|
{
|
||||||
var func = this._ifacefuncs[i];
|
var func = this._ifacefuncs[i];
|
||||||
if (!(typeof this[func] == "function"))
|
if (!(typeof this[func] == "function"))
|
||||||
@ -194,6 +220,11 @@
|
|||||||
"function '" + func + "' not implemented.");
|
"function '" + func + "' not implemented.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.init)
|
||||||
|
{
|
||||||
|
this.init.apply(this, arguments);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
123
etemplate/js/et2_template.js
Normal file
123
etemplate/js/et2_template.js
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
/**
|
||||||
|
* eGroupWare eTemplate2 - JS Template 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$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*egw:uses
|
||||||
|
et2_widget;
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class which implements the "template" XET-Tag. When the id parameter is set,
|
||||||
|
* the template class checks whether another template with this id already
|
||||||
|
* exists. If yes, this template is removed from the DOM tree, copied and
|
||||||
|
* inserted in place of this template.
|
||||||
|
*
|
||||||
|
* TODO: Check whether this widget behaves as it should.
|
||||||
|
*/
|
||||||
|
et2_template = et2_DOMWidget.extend({
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes this template widget as a simple container.
|
||||||
|
*/
|
||||||
|
init: function(_parent) {
|
||||||
|
this.proxiedTemplate = null;
|
||||||
|
this.isProxied = false;
|
||||||
|
|
||||||
|
this.div = document.createElement("div");
|
||||||
|
|
||||||
|
this._super.apply(this, arguments);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
if (this._parent && this._parent.implements(et2_IDOMNode)) {
|
||||||
|
var parentNode = this._parent.getDOMNode();
|
||||||
|
|
||||||
|
if (parentNode)
|
||||||
|
{
|
||||||
|
if (this.proxiedTemplate)
|
||||||
|
{
|
||||||
|
this.proxiedTemplate.setParentDOMNode(parentNode);
|
||||||
|
}
|
||||||
|
else if (!this.isProxied)
|
||||||
|
{
|
||||||
|
this.setParentDOMNode(parentNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
makeProxied: function() {
|
||||||
|
if (!this.isProxied)
|
||||||
|
{
|
||||||
|
this.detatchFromDOM();
|
||||||
|
this.div = null;
|
||||||
|
this.parentNode = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// Disallow adding any new node to this template
|
||||||
|
this.supportedWidgetClasses = [];
|
||||||
|
|
||||||
|
// Call the parent change event function
|
||||||
|
this.onSetParent();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this._super(_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getDOMNode: function(_fromProxy) {
|
||||||
|
return this.div;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
et2_register_widget(et2_template, ["template"]);
|
||||||
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*egw:uses
|
/*egw:uses
|
||||||
|
jquery.jquery;
|
||||||
et2_xml;
|
et2_xml;
|
||||||
et2_common;
|
et2_common;
|
||||||
et2_inheritance;
|
et2_inheritance;
|
||||||
@ -29,7 +30,7 @@ var et2_registry = {};
|
|||||||
function et2_register_widget(_constructor, _types)
|
function et2_register_widget(_constructor, _types)
|
||||||
{
|
{
|
||||||
// Iterate over all given types and register those
|
// Iterate over all given types and register those
|
||||||
for (var i in _types)
|
for (var i = 0; i < _types.length; i++)
|
||||||
{
|
{
|
||||||
var type = _types[i].toLowerCase();
|
var type = _types[i].toLowerCase();
|
||||||
|
|
||||||
@ -71,6 +72,8 @@ et2_widget = Class.extend({
|
|||||||
// Copy the parent parameter and add this widget to its parent children
|
// Copy the parent parameter and add this widget to its parent children
|
||||||
// list.
|
// list.
|
||||||
this._parent = _parent;
|
this._parent = _parent;
|
||||||
|
this.onSetParent();
|
||||||
|
|
||||||
if (_parent != null)
|
if (_parent != null)
|
||||||
{
|
{
|
||||||
this._parent.addChild(this);
|
this._parent.addChild(this);
|
||||||
@ -79,6 +82,10 @@ et2_widget = Class.extend({
|
|||||||
this._children = [];
|
this._children = [];
|
||||||
this.id = "";
|
this.id = "";
|
||||||
this.type = _type;
|
this.type = _type;
|
||||||
|
|
||||||
|
// The supported widget classes array defines a whitelist for all widget
|
||||||
|
// classes or interfaces child widgets have to support.
|
||||||
|
this.supportedWidgetClasses = [et2_widget];
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -92,7 +99,7 @@ et2_widget = Class.extend({
|
|||||||
destroy: function() {
|
destroy: function() {
|
||||||
|
|
||||||
// Call the destructor of all children
|
// Call the destructor of all children
|
||||||
for (var i = this._children.length; i >= 0; i--)
|
for (var i = this._children.length - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
this._children[i].destroy();
|
this._children[i].destroy();
|
||||||
}
|
}
|
||||||
@ -106,6 +113,41 @@ et2_widget = Class.extend({
|
|||||||
// Delete all references to other objects
|
// Delete all references to other objects
|
||||||
this._children = [];
|
this._children = [];
|
||||||
this._parent = null;
|
this._parent = null;
|
||||||
|
this.onSetParent();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a copy of this widget. The parameters given are passed to the
|
||||||
|
* constructor of the copied object. If the parameters are omitted, _parent
|
||||||
|
* is defaulted to null
|
||||||
|
*/
|
||||||
|
clone: function(_parent, _type) {
|
||||||
|
|
||||||
|
// Default _parent to null
|
||||||
|
if (typeof _parent == "undefined")
|
||||||
|
{
|
||||||
|
_parent = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the copy
|
||||||
|
var copy = new (this.constructor)(_parent, _type);
|
||||||
|
|
||||||
|
// Create a clone of all child elements
|
||||||
|
for (var i = 0; i < this._children.length; i++)
|
||||||
|
{
|
||||||
|
this._children[i].clone(copy, this._children[i].type);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy all properties for which a setter function exists
|
||||||
|
for (var key in this)
|
||||||
|
{
|
||||||
|
if (key != "id" && typeof copy["set_" + key] == "function")
|
||||||
|
{
|
||||||
|
copy["set_" + key](this[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return copy;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -115,6 +157,14 @@ et2_widget = Class.extend({
|
|||||||
return this._parent;
|
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.
|
* Returns the list of children of this widget.
|
||||||
*/
|
*/
|
||||||
@ -154,14 +204,15 @@ et2_widget = Class.extend({
|
|||||||
* @param _idx is the position at which the element should be added.
|
* @param _idx is the position at which the element should be added.
|
||||||
*/
|
*/
|
||||||
insertChild: function(_node, _idx) {
|
insertChild: function(_node, _idx) {
|
||||||
if (_node instanceof et2_widget)
|
// Check whether the node is one of the supported widget classes.
|
||||||
|
if (this.isOfSupportedWidgetClass(_node))
|
||||||
{
|
{
|
||||||
_node.parent = this;
|
_node.parent = this;
|
||||||
this._children.splice(_idx, 0, _node);
|
this._children.splice(_idx, 0, _node);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw("_node is not an instance of et2_widget!");
|
throw("_node is not supported by this widget class!");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -176,6 +227,7 @@ et2_widget = Class.extend({
|
|||||||
{
|
{
|
||||||
// This element is no longer parent of the child
|
// This element is no longer parent of the child
|
||||||
_node._parent = null;
|
_node._parent = null;
|
||||||
|
_node.onSetParent();
|
||||||
|
|
||||||
this._children.splice(idx, 1);
|
this._children.splice(idx, 1);
|
||||||
}
|
}
|
||||||
@ -205,6 +257,18 @@ et2_widget = Class.extend({
|
|||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
isOfSupportedWidgetClass: function(_obj)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < this.supportedWidgetClasses.length; i++)
|
||||||
|
{
|
||||||
|
if (_obj.instanceOf(this.supportedWidgetClasses[i]))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the widget tree from an XML node
|
* Loads the widget tree from an XML node
|
||||||
*/
|
*/
|
||||||
@ -221,6 +285,20 @@ et2_widget = Class.extend({
|
|||||||
var node = _node.childNodes[i];
|
var node = _node.childNodes[i];
|
||||||
var widgetType = node.nodeName.toLowerCase();
|
var widgetType = node.nodeName.toLowerCase();
|
||||||
|
|
||||||
|
if (widgetType == "#comment")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (widgetType == "#text")
|
||||||
|
{
|
||||||
|
if (node.data.replace(/^\s+|\s+$/g, ''))
|
||||||
|
{
|
||||||
|
this.loadContent(node.data);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Check whether a widget with the given type is registered.
|
// Check whether a widget with the given type is registered.
|
||||||
var constructor = typeof et2_registry[widgetType] == "undefined" ?
|
var constructor = typeof et2_registry[widgetType] == "undefined" ?
|
||||||
et2_placeholder : et2_registry[widgetType];
|
et2_placeholder : et2_registry[widgetType];
|
||||||
@ -247,6 +325,12 @@ et2_widget = Class.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called whenever textNodes are loaded from the XML tree
|
||||||
|
*/
|
||||||
|
loadContent: function(_content) {
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls the setter of each property with its current value, calls the
|
* Calls the setter of each property with its current value, calls the
|
||||||
* update function of all child nodes.
|
* update function of all child nodes.
|
||||||
@ -263,7 +347,7 @@ et2_widget = Class.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Call the update function of all children.
|
// Call the update function of all children.
|
||||||
for (var i in this._children)
|
for (var i = 0; i < this._children.length; i++)
|
||||||
{
|
{
|
||||||
this._children[i].update();
|
this._children[i].update();
|
||||||
}
|
}
|
||||||
@ -285,9 +369,9 @@ et2_widget = Class.extend({
|
|||||||
/**
|
/**
|
||||||
* Interface for all widget classes, which are based on a DOM node.
|
* Interface for all widget classes, which are based on a DOM node.
|
||||||
*/
|
*/
|
||||||
et2_IDOMNode = {
|
et2_IDOMNode = new Interface({
|
||||||
getDOMNode: function() {}
|
getDOMNode: function() {}
|
||||||
}
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract widget class which can be inserted into the DOM. All widget classes
|
* Abstract widget class which can be inserted into the DOM. All widget classes
|
||||||
@ -301,17 +385,11 @@ et2_DOMWidget = et2_widget.extend(et2_IDOMNode, {
|
|||||||
* object (if available) and passes it to its own "createDOMNode" function
|
* object (if available) and passes it to its own "createDOMNode" function
|
||||||
*/
|
*/
|
||||||
init: function(_parent, _type) {
|
init: function(_parent, _type) {
|
||||||
|
this.parentNode = null;
|
||||||
|
this.visible = true;
|
||||||
|
|
||||||
// Call the inherited constructor
|
// Call the inherited constructor
|
||||||
this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
|
|
||||||
this.parentNode = null;
|
|
||||||
|
|
||||||
// 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());
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy: function() {
|
destroy: function() {
|
||||||
@ -321,14 +399,22 @@ et2_DOMWidget = et2_widget.extend(et2_IDOMNode, {
|
|||||||
this._super();
|
this._super();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onSetParent: 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());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
detatchFromDOM: function() {
|
detatchFromDOM: function() {
|
||||||
if (this.parentNode)
|
if (this.parentNode)
|
||||||
{
|
{
|
||||||
var node = this.getDOMNode();
|
var node = this.getDOMNode();
|
||||||
|
|
||||||
if (node)
|
if (node)
|
||||||
{
|
{
|
||||||
this.parentNode.removeChild(node);
|
this.parentNode.removeChild(node);
|
||||||
|
this.parentNode = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -366,6 +452,17 @@ et2_DOMWidget = et2_widget.extend(et2_IDOMNode, {
|
|||||||
{
|
{
|
||||||
node.setAttribute("id", _value);
|
node.setAttribute("id", _value);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
set_visible: function(_value) {
|
||||||
|
/*if (_value != this.visible)
|
||||||
|
{
|
||||||
|
var node = this.getDOMNode();
|
||||||
|
if (node)
|
||||||
|
{
|
||||||
|
node.set
|
||||||
|
}
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -376,13 +473,40 @@ et2_DOMWidget = et2_widget.extend(et2_IDOMNode, {
|
|||||||
et2_placeholder = et2_DOMWidget.extend({
|
et2_placeholder = et2_DOMWidget.extend({
|
||||||
|
|
||||||
init: function() {
|
init: function() {
|
||||||
this.placeDiv = document.createElement("span");
|
// Create the placeholder div
|
||||||
|
this.placeDiv = $j(document.createElement("span"))
|
||||||
|
.addClass("et2_placeholder");
|
||||||
|
|
||||||
|
// The attrNodes object will hold the DOM nodes which represent the
|
||||||
|
// values of this object
|
||||||
|
this.attrNodes = {};
|
||||||
|
|
||||||
this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
|
|
||||||
|
var headerNode = $j(document.createElement("span"))
|
||||||
|
.text(this.type)
|
||||||
|
.addClass("et2_caption");
|
||||||
|
$j(this.placeDiv).append(headerNode);
|
||||||
|
},
|
||||||
|
|
||||||
|
loadAttributes: function(_attrs) {
|
||||||
|
for (var i = 0; i < _attrs.length; i++)
|
||||||
|
{
|
||||||
|
var attr = _attrs[i];
|
||||||
|
|
||||||
|
if (typeof this.attrNodes[attr.name] == "undefined")
|
||||||
|
{
|
||||||
|
this.attrNodes[attr.name] = $j(document.createElement("span"))
|
||||||
|
.addClass("et2_attr");
|
||||||
|
this.placeDiv.append(this.attrNodes[attr.name]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.attrNodes[attr.name].text(attr.name + "=" + attr.value);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getDOMNode: function() {
|
getDOMNode: function() {
|
||||||
return this.placeDiv;
|
return this.placeDiv[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -404,3 +528,12 @@ et2_container = et2_DOMWidget.extend({
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for all widgets which support returning a value
|
||||||
|
*/
|
||||||
|
|
||||||
|
et2_IValue = new Interface({
|
||||||
|
getValue: function() {}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,7 +31,21 @@ function et2_loadXMLFromURL(_url, _callback, _context)
|
|||||||
xmldoc.onreadystatechange = function() {
|
xmldoc.onreadystatechange = function() {
|
||||||
if (xmldoc && xmldoc.readyState == 4)
|
if (xmldoc && xmldoc.readyState == 4)
|
||||||
{
|
{
|
||||||
_callback.call(_context, xmldoc);
|
// Find the root node - the root node is the node which is not
|
||||||
|
// the "xml", not a text node and not a comment node - those nodes
|
||||||
|
// are marked with an "#"
|
||||||
|
for (var i = 0; i < xmldoc.childNodes.length; i++)
|
||||||
|
{
|
||||||
|
var nodeName = xmldoc.childNodes[i].nodeName;
|
||||||
|
if (nodeName != "xml" && nodeName.charAt(0) != "#")
|
||||||
|
{
|
||||||
|
// Call the callback function and pass the current node
|
||||||
|
_callback.call(_context, xmldoc.childNodes[i]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw("Could not find XML root node.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
13
etemplate/js/test/et2_test_template.xet
Normal file
13
etemplate/js/test/et2_test_template.xet
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<overlay>
|
||||||
|
<template id="test" template="" lang="" group="0" version="1">
|
||||||
|
<description value="This description is inside the 'test' template" options=""/>
|
||||||
|
</template>
|
||||||
|
<description value="Test template:" options=""/>
|
||||||
|
<template id="test" />
|
||||||
|
<template id="test" />
|
||||||
|
<template id="test" />
|
||||||
|
<template id="test" />
|
||||||
|
<template id="test" />
|
||||||
|
</overlay>
|
||||||
|
|
8176
etemplate/js/test/jquery.js
vendored
Normal file
8176
etemplate/js/test/jquery.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -2,20 +2,92 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>ET2 - Test</title>
|
<title>ET2 - Test</title>
|
||||||
|
|
||||||
|
<script src="jquery.js"></script>
|
||||||
<script src="../et2_xml.js"></script>
|
<script src="../et2_xml.js"></script>
|
||||||
<script src="../et2_inheritance.js"></script>
|
<script src="../et2_inheritance.js"></script>
|
||||||
<script src="../et2_common.js"></script>
|
<script src="../et2_common.js"></script>
|
||||||
<script src="../et2_widget.js"></script>
|
<script src="../et2_widget.js"></script>
|
||||||
</head>
|
<script src="../et2_template.js"></script>
|
||||||
<body onload="init();">
|
<script src="../et2_description.js"></script>
|
||||||
<script>
|
<style type="text/css">
|
||||||
var doc = null;
|
body {
|
||||||
|
font-family: Lucida Grande, sans-serif;
|
||||||
|
font-size: 10pt;
|
||||||
|
}
|
||||||
|
|
||||||
function init() {
|
#linklist a {
|
||||||
et2_loadXMLFromURL("../../../timesheet/templates/default/edit.xet",
|
color: blue;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#linklist a:visited {
|
||||||
|
color: blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#linklist a:hover {
|
||||||
|
color: #5050FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
#container {
|
||||||
|
margin: 10px;
|
||||||
|
border: 1px solid gray;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
color: #111;
|
||||||
|
margin: 30px 0 5px 0;
|
||||||
|
border-bottom: 1px solid #111;
|
||||||
|
}
|
||||||
|
|
||||||
|
.et2_placeholder {
|
||||||
|
display: inline-block;
|
||||||
|
border: 1px solid cornflowerblue;
|
||||||
|
background-color: #FCFCFC;
|
||||||
|
padding: 3px;
|
||||||
|
margin: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.et2_placeholder .et2_caption {
|
||||||
|
display: block;
|
||||||
|
font-size: 8pt;
|
||||||
|
margin: 0 0 5px 0;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #2E2E2E;
|
||||||
|
text-shadow: rgba(255, 255, 255, 0.5) 0 1px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.et2_placeholder .et2_attr {
|
||||||
|
display: block;
|
||||||
|
font-size: 8pt;
|
||||||
|
color: #3030A0;
|
||||||
|
margin: 2px 0 2px 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>EGroupware ETemplate2 Test</h1>
|
||||||
|
<div class="header">Choose one of the following tests:</div>
|
||||||
|
<div id="linklist">
|
||||||
|
<a href="#" onclick="open_xet('../../../timesheet/templates/default/edit.xet');">Timesheet edit dialog</a>
|
||||||
|
<a href="#" onclick="open_xet('et2_test_template.xet');">Template proxy test</a>
|
||||||
|
</div>
|
||||||
|
<div class="header">ETemplate2 container:</div>
|
||||||
|
<div id="container"></div>
|
||||||
|
<script>
|
||||||
|
var container = null;
|
||||||
|
|
||||||
|
function open_xet(file) {
|
||||||
|
et2_loadXMLFromURL(file,
|
||||||
function(_xmldoc) {
|
function(_xmldoc) {
|
||||||
var container = new et2_container(null);
|
if (container != null)
|
||||||
container.setParentDOMNode(document.body);
|
{
|
||||||
|
container.destroy();
|
||||||
|
container = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
container = new et2_container(null);
|
||||||
|
container.setParentDOMNode(document.getElementById("container"));
|
||||||
container.loadFromXML(_xmldoc);
|
container.loadFromXML(_xmldoc);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user