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
|
||||
* 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() {}
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* Human = Class.extend(IBreathingObject, {
|
||||
* walk: function() {
|
||||
@ -72,6 +72,15 @@
|
||||
// check whether a
|
||||
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
|
||||
* to implement to the class prototype.
|
||||
@ -84,15 +93,23 @@
|
||||
|
||||
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)
|
||||
{
|
||||
prototype["_ifacefuncs"].push(key);
|
||||
for (var key in iface)
|
||||
{
|
||||
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]);
|
||||
}
|
||||
@ -109,7 +126,21 @@
|
||||
}
|
||||
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)
|
||||
this.Class = function(){};
|
||||
@ -179,13 +210,8 @@
|
||||
// All construction is actually done in the init method
|
||||
if (!initializing)
|
||||
{
|
||||
if (this.init)
|
||||
{
|
||||
this.init.apply(this, arguments);
|
||||
}
|
||||
|
||||
// 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];
|
||||
if (!(typeof this[func] == "function"))
|
||||
@ -194,6 +220,11 @@
|
||||
"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
|
||||
jquery.jquery;
|
||||
et2_xml;
|
||||
et2_common;
|
||||
et2_inheritance;
|
||||
@ -29,7 +30,7 @@ var et2_registry = {};
|
||||
function et2_register_widget(_constructor, _types)
|
||||
{
|
||||
// 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();
|
||||
|
||||
@ -71,6 +72,8 @@ et2_widget = Class.extend({
|
||||
// Copy the parent parameter and add this widget to its parent children
|
||||
// list.
|
||||
this._parent = _parent;
|
||||
this.onSetParent();
|
||||
|
||||
if (_parent != null)
|
||||
{
|
||||
this._parent.addChild(this);
|
||||
@ -79,6 +82,10 @@ et2_widget = Class.extend({
|
||||
this._children = [];
|
||||
this.id = "";
|
||||
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() {
|
||||
|
||||
// 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();
|
||||
}
|
||||
@ -106,6 +113,41 @@ et2_widget = Class.extend({
|
||||
// Delete all references to other objects
|
||||
this._children = [];
|
||||
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;
|
||||
},
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@ -154,14 +204,15 @@ et2_widget = Class.extend({
|
||||
* @param _idx is the position at which the element should be added.
|
||||
*/
|
||||
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;
|
||||
this._children.splice(_idx, 0, _node);
|
||||
}
|
||||
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
|
||||
_node._parent = null;
|
||||
_node.onSetParent();
|
||||
|
||||
this._children.splice(idx, 1);
|
||||
}
|
||||
@ -205,6 +257,18 @@ et2_widget = Class.extend({
|
||||
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
|
||||
*/
|
||||
@ -221,6 +285,20 @@ et2_widget = Class.extend({
|
||||
var node = _node.childNodes[i];
|
||||
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.
|
||||
var constructor = typeof et2_registry[widgetType] == "undefined" ?
|
||||
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
|
||||
* update function of all child nodes.
|
||||
@ -263,7 +347,7 @@ et2_widget = Class.extend({
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
@ -285,9 +369,9 @@ et2_widget = Class.extend({
|
||||
/**
|
||||
* Interface for all widget classes, which are based on a DOM node.
|
||||
*/
|
||||
et2_IDOMNode = {
|
||||
et2_IDOMNode = new Interface({
|
||||
getDOMNode: function() {}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
init: function(_parent, _type) {
|
||||
this.parentNode = null;
|
||||
this.visible = true;
|
||||
|
||||
// Call the inherited constructor
|
||||
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() {
|
||||
@ -321,14 +399,22 @@ et2_DOMWidget = et2_widget.extend(et2_IDOMNode, {
|
||||
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() {
|
||||
if (this.parentNode)
|
||||
{
|
||||
var node = this.getDOMNode();
|
||||
|
||||
if (node)
|
||||
{
|
||||
this.parentNode.removeChild(node);
|
||||
this.parentNode = null;
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -366,6 +452,17 @@ et2_DOMWidget = et2_widget.extend(et2_IDOMNode, {
|
||||
{
|
||||
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({
|
||||
|
||||
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);
|
||||
|
||||
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() {
|
||||
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() {
|
||||
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>
|
||||
<title>ET2 - Test</title>
|
||||
|
||||
<script src="jquery.js"></script>
|
||||
<script src="../et2_xml.js"></script>
|
||||
<script src="../et2_inheritance.js"></script>
|
||||
<script src="../et2_common.js"></script>
|
||||
<script src="../et2_widget.js"></script>
|
||||
</head>
|
||||
<body onload="init();">
|
||||
<script>
|
||||
var doc = null;
|
||||
<script src="../et2_template.js"></script>
|
||||
<script src="../et2_description.js"></script>
|
||||
<style type="text/css">
|
||||
body {
|
||||
font-family: Lucida Grande, sans-serif;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
function init() {
|
||||
et2_loadXMLFromURL("../../../timesheet/templates/default/edit.xet",
|
||||
#linklist a {
|
||||
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) {
|
||||
var container = new et2_container(null);
|
||||
container.setParentDOMNode(document.body);
|
||||
if (container != null)
|
||||
{
|
||||
container.destroy();
|
||||
container = null;
|
||||
}
|
||||
|
||||
container = new et2_container(null);
|
||||
container.setParentDOMNode(document.getElementById("container"));
|
||||
container.loadFromXML(_xmldoc);
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user