mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-30 03:43:40 +01:00
Moved 'getValues' function to etemplate2 class, added 'et2_surroundingsMgr' class, which is capable of managing DOM-Nodes which are inserted around an widget (see set_label function in et2_input and showMessage function in et2_baseWidget as an example of how to use it), added parsing server side validation errors
This commit is contained in:
parent
24e34f7927
commit
86414e7daa
@ -95,6 +95,7 @@ var et2_DOMWidget = et2_widget.extend(et2_IDOMNode, {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this._disabled = false;
|
this._disabled = false;
|
||||||
|
this._surroundingsMgr = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -107,6 +108,12 @@ var et2_DOMWidget = et2_widget.extend(et2_IDOMNode, {
|
|||||||
this.parentNode = null;
|
this.parentNode = null;
|
||||||
this._attachSet = {};
|
this._attachSet = {};
|
||||||
|
|
||||||
|
if (this._surroundingsMgr)
|
||||||
|
{
|
||||||
|
this._surroundingsMgr.destroy();
|
||||||
|
this._surroundingsMgr = null;
|
||||||
|
}
|
||||||
|
|
||||||
this._super();
|
this._super();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -158,6 +165,13 @@ var et2_DOMWidget = et2_widget.extend(et2_IDOMNode, {
|
|||||||
(node != this._attachSet.node ||
|
(node != this._attachSet.node ||
|
||||||
this.parentNode != this._attachSet.parent))
|
this.parentNode != this._attachSet.parent))
|
||||||
{
|
{
|
||||||
|
// If the surroundings manager exists, surround the DOM-Node of this
|
||||||
|
// widget with the DOM-Nodes inside the surroundings manager.
|
||||||
|
if (this._surroundingsMgr)
|
||||||
|
{
|
||||||
|
node = this._surroundingsMgr.getDOMNode(node);
|
||||||
|
}
|
||||||
|
|
||||||
this.parentNode.appendChild(node);
|
this.parentNode.appendChild(node);
|
||||||
|
|
||||||
// Store the currently attached nodes
|
// Store the currently attached nodes
|
||||||
@ -176,6 +190,15 @@ var et2_DOMWidget = et2_widget.extend(et2_IDOMNode, {
|
|||||||
return this.parentNode != null;
|
return this.parentNode != null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getSurroundings: function() {
|
||||||
|
if (!this._surroundingsMgr)
|
||||||
|
{
|
||||||
|
this._surroundingsMgr = new et2_surroundingsMgr(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._surroundingsMgr;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the parent DOM node of this element. If another parent node is already
|
* Set the parent DOM node of this element. If another parent node is already
|
||||||
* set, this widget removes itself from the DOM tree
|
* set, this widget removes itself from the DOM tree
|
||||||
@ -283,4 +306,210 @@ var et2_DOMWidget = et2_widget.extend(et2_IDOMNode, {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The surroundings manager class allows to append or prepend elements around
|
||||||
|
* an widget node.
|
||||||
|
*/
|
||||||
|
var et2_surroundingsMgr = Class.extend({
|
||||||
|
|
||||||
|
init: function(_widget) {
|
||||||
|
this.widget = _widget;
|
||||||
|
|
||||||
|
this._widgetContainer = null;
|
||||||
|
this._widgetSurroundings = [];
|
||||||
|
this._widgetPlaceholder = null;
|
||||||
|
this._widgetNode = null;
|
||||||
|
this._ownPlaceholder = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy: function() {
|
||||||
|
this._widgetContainer = null;
|
||||||
|
this._widgetSurroundings = null;
|
||||||
|
this._widgetPlaceholder = null;
|
||||||
|
this._widgetNode = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
prependDOMNode: function(_node) {
|
||||||
|
this._widgetSurroundings.unshift(_node);
|
||||||
|
this._surroundingsUpdated = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
appendDOMNode: function(_node) {
|
||||||
|
// Append an placeholder first if none is existing yet
|
||||||
|
if (this._ownPlaceholder && this._widgetPlaceholder == null)
|
||||||
|
{
|
||||||
|
this._widgetPlaceholder = document.createElement("span");
|
||||||
|
this._widgetSurroundings.push(this._widgetPlaceholder);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append the given node
|
||||||
|
this._widgetSurroundings.push(_node);
|
||||||
|
this._surroundingsUpdated = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
insertDOMNode: function(_node) {
|
||||||
|
if (!this._ownPlaceholder || this._widgetPlaceholder == null)
|
||||||
|
{
|
||||||
|
this.appendDOMNode(_node);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the index of the widget placeholder and delete it, insert the
|
||||||
|
// given node instead
|
||||||
|
var idx = this._widgetSurroundings.indexOf(this._widgetPlaceholder);
|
||||||
|
this._widgetSurroundings.splice(idx, 1, _node);
|
||||||
|
|
||||||
|
// Delete the reference to the own placeholder
|
||||||
|
this._widgetPlaceholder = null;
|
||||||
|
this._ownPlaceholder = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
removeDOMNode: function(_node) {
|
||||||
|
for (var i = 0; i < this._widgetSurroundings.length; i++)
|
||||||
|
{
|
||||||
|
if (this._widgetSurroundings[i] == _node)
|
||||||
|
{
|
||||||
|
this._widgetSurroundings.splice(i, 1);
|
||||||
|
this._surroundingsUpdated = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setWidgetPlaceholder: function(_node) {
|
||||||
|
if (_node != this._widgetPlaceholder)
|
||||||
|
{
|
||||||
|
if (_node != null && this._ownPlaceholder && this._widgetPlaceholder != null)
|
||||||
|
{
|
||||||
|
// Delete the current placeholder which was created by the
|
||||||
|
// widget itself
|
||||||
|
var idx = this._widgetSurroundings.indexOf(this._widgetPlaceholder);
|
||||||
|
this._widgetSurroundings.splice(idx, 1);
|
||||||
|
|
||||||
|
// Delete any reference to the own placeholder and set the
|
||||||
|
// _ownPlaceholder flag to false
|
||||||
|
this._widgetPlaceholder = null;
|
||||||
|
this._ownPlaceholder = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._ownPlaceholder = (_node == null);
|
||||||
|
this._widgetPlaceholder = _node;
|
||||||
|
this._surroundingsUpdated = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_rebuildContainer: function() {
|
||||||
|
// Return if there has been no change in the "surroundings-data"
|
||||||
|
if (!this._surroundingsUpdated)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the widget container
|
||||||
|
if (this._widgetSurroundings.length > 0)
|
||||||
|
{
|
||||||
|
// Check whether the widgetPlaceholder is really inside the DOM-Tree
|
||||||
|
var hasPlaceholder = et2_hasChild(this._widgetSurroundings,
|
||||||
|
this._widgetPlaceholder);
|
||||||
|
|
||||||
|
// If not, append another widget placeholder
|
||||||
|
if (!hasPlaceholder)
|
||||||
|
{
|
||||||
|
this._widgetPlaceholder = document.createElement("span");
|
||||||
|
this._widgetSurroundings.push(this._widgetPlaceholder);
|
||||||
|
|
||||||
|
this._ownPlaceholder = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the surroundings array only contains one element, set this one
|
||||||
|
// as the widget container
|
||||||
|
if (this._widgetSurroundings.length == 1)
|
||||||
|
{
|
||||||
|
if (this._widgetSurroundings[0] == this._widgetPlaceholder)
|
||||||
|
{
|
||||||
|
this._widgetContainer = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this._widgetContainer = this._widgetSurroundings[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Create an outer "span" as widgetContainer
|
||||||
|
this._widgetContainer = document.createElement("span");
|
||||||
|
|
||||||
|
// Append the children inside the widgetSurroundings array to
|
||||||
|
// the widget container
|
||||||
|
for (var i = 0; i < this._widgetSurroundings.length; i++)
|
||||||
|
{
|
||||||
|
this._widgetContainer.appendChild(this._widgetSurroundings[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this._widgetContainer = null;
|
||||||
|
this._widgetPlaceholder = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._surroundingsUpdated = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
update: function() {
|
||||||
|
if (this._surroundingsUpdated)
|
||||||
|
{
|
||||||
|
var attached = this.widget ? this.widget.isAttached() : false;
|
||||||
|
|
||||||
|
// Reattach the widget - this will call the "getDOMNode" function
|
||||||
|
// and trigger the _rebuildContainer function.
|
||||||
|
if (attached && this.widget)
|
||||||
|
{
|
||||||
|
this.widget.detatchFromDOM();
|
||||||
|
this.widget.attachToDOM();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getDOMNode: function(_widgetNode) {
|
||||||
|
// Update the whole widgetContainer if this is not the first time this
|
||||||
|
// function has been called but the widget node has changed.
|
||||||
|
if (this._widgetNode != null && this._widgetNode != _widgetNode)
|
||||||
|
{
|
||||||
|
this._surroundingsUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy a reference to the given node
|
||||||
|
this._widgetNode = _widgetNode;
|
||||||
|
|
||||||
|
// Build the container if it didn't exist yet.
|
||||||
|
var updated = this._rebuildContainer(true);
|
||||||
|
|
||||||
|
// Return the widget node itself if there are no surroundings arround
|
||||||
|
// it
|
||||||
|
if (this._widgetContainer == null)
|
||||||
|
{
|
||||||
|
return _widgetNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace the widgetPlaceholder with the given widget node if the
|
||||||
|
// widgetContainer has been updated
|
||||||
|
if (updated)
|
||||||
|
{
|
||||||
|
this._widgetPlaceholder.parentNode.replaceChild(_widgetNode,
|
||||||
|
this._widgetPlaceholder);
|
||||||
|
if (!this._ownPlaceholder)
|
||||||
|
{
|
||||||
|
this._widgetPlaceholder = _widgetNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the widget container
|
||||||
|
return this._widgetContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,10 +58,7 @@ var et2_baseWidget = et2_DOMWidget.extend(et2_IAligned, {
|
|||||||
|
|
||||||
this.node = null;
|
this.node = null;
|
||||||
this.statustext = "";
|
this.statustext = "";
|
||||||
|
this._messageDiv = null;
|
||||||
this._labelContainer = null;
|
|
||||||
this._widgetPlaceholder = null;
|
|
||||||
|
|
||||||
this._tooltipElem = null;
|
this._tooltipElem = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -69,6 +66,113 @@ var et2_baseWidget = et2_DOMWidget.extend(et2_IAligned, {
|
|||||||
this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
|
|
||||||
this.node = null;
|
this.node = null;
|
||||||
|
this._messageDiv = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The setMessage function can be used to attach a small message box to the
|
||||||
|
* widget. This is e.g. used to display validation errors or success messages
|
||||||
|
*
|
||||||
|
* @param _text is the text which should be displayed as a message
|
||||||
|
* @param _type is an css class which is attached to the message box.
|
||||||
|
* Currently available are "hint", "success" and "validation_error", defaults
|
||||||
|
* to "hint"
|
||||||
|
* @param _floating if true, the object will be in one row with the element,
|
||||||
|
* defaults to true
|
||||||
|
* @param _prepend if set, the message is displayed behind the widget node
|
||||||
|
* instead of before. Defaults to false.
|
||||||
|
*/
|
||||||
|
showMessage: function(_text, _type, _floating, _prepend) {
|
||||||
|
|
||||||
|
// Preset the parameters
|
||||||
|
if (typeof _type == "undefined")
|
||||||
|
{
|
||||||
|
_type = "hint"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof _floating == "undefined")
|
||||||
|
{
|
||||||
|
_floating = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof _prepend == "undefined")
|
||||||
|
{
|
||||||
|
_prepend = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var surr = this.getSurroundings();
|
||||||
|
|
||||||
|
// Remove the message div from the surroundings before creating a new
|
||||||
|
// one
|
||||||
|
this.hideMessgae(false, true);
|
||||||
|
|
||||||
|
// Create the message div and add it to the "surroundings" manager
|
||||||
|
this._messageDiv = $j(document.createElement("div"))
|
||||||
|
.addClass("message")
|
||||||
|
.addClass(_type)
|
||||||
|
.addClass(_floating ? "floating" : "")
|
||||||
|
.text(_text);
|
||||||
|
|
||||||
|
// Decide whether to prepend or append the div
|
||||||
|
if (_prepend)
|
||||||
|
{
|
||||||
|
surr.prependDOMNode(this._messageDiv[0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
surr.appendDOMNode(this._messageDiv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
surr.update();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The hideMessgae function can be used to hide a previously shown message.
|
||||||
|
*
|
||||||
|
* @param _fade if true, the message div will fade out, otherwise the message
|
||||||
|
* div is removed immediately. Defaults to true.
|
||||||
|
* @param _noUpdate is used internally to prevent an update of the surroundings
|
||||||
|
* manager.
|
||||||
|
*/
|
||||||
|
hideMessgae: function(_fade, _noUpdate) {
|
||||||
|
if (typeof _fade == "undefined")
|
||||||
|
{
|
||||||
|
_fade = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof _noUpdate == "undefined")
|
||||||
|
{
|
||||||
|
_noUpdate = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the message from the surroundings manager and remove the
|
||||||
|
// reference to it
|
||||||
|
if (this._messageDiv != null)
|
||||||
|
{
|
||||||
|
var surr = this.getSurroundings();
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var _done = function() {
|
||||||
|
surr.removeDOMNode(self._messageDiv[0]);
|
||||||
|
self._messageDiv = null;
|
||||||
|
|
||||||
|
// Update the surroundings manager
|
||||||
|
if (!_noUpdate)
|
||||||
|
{
|
||||||
|
surr.update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Either fade out or directly call the function which removes the div
|
||||||
|
if (_fade)
|
||||||
|
{
|
||||||
|
this._messageDiv.fadeOut("fast", _done);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_done();
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
detatchFromDOM: function() {
|
detatchFromDOM: function() {
|
||||||
@ -127,6 +231,15 @@ var et2_baseWidget = et2_DOMWidget.extend(et2_IAligned, {
|
|||||||
return this.getDOMNode(this);
|
return this.getDOMNode(this);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
click: function(_node) {
|
||||||
|
if (this.onclick)
|
||||||
|
{
|
||||||
|
return this.onclick.call(_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
set_statustext: function(_value) {
|
set_statustext: function(_value) {
|
||||||
// Don't execute the code below, if no tooltip will be attached/detached
|
// Don't execute the code below, if no tooltip will be attached/detached
|
||||||
if (_value == "" && !this._tooltipElem)
|
if (_value == "" && !this._tooltipElem)
|
||||||
@ -156,15 +269,6 @@ var et2_baseWidget = et2_DOMWidget.extend(et2_IAligned, {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
click: function(_node) {
|
|
||||||
if (this.onclick)
|
|
||||||
{
|
|
||||||
return this.onclick.call(_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
set_align: function(_value) {
|
set_align: function(_value) {
|
||||||
this.align = _value;
|
this.align = _value;
|
||||||
},
|
},
|
||||||
|
@ -566,3 +566,29 @@ function et2_cloneObject(_obj)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the given array of nodes or their children contains the given
|
||||||
|
* child node.
|
||||||
|
*/
|
||||||
|
function et2_hasChild(_nodes, _child)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < _nodes.length; i++)
|
||||||
|
{
|
||||||
|
if (_nodes[i] == _child)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (_nodes[i].childNodes)
|
||||||
|
{
|
||||||
|
var res = et2_hasChild(_nodes[i].childNodes, _child);
|
||||||
|
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -62,6 +62,12 @@ var et2_inputWidget = et2_valueWidget.extend(et2_IInput, {
|
|||||||
"name": "onchange",
|
"name": "onchange",
|
||||||
"type": "js",
|
"type": "js",
|
||||||
"description": "JS code which is executed when the value changes."
|
"description": "JS code which is executed when the value changes."
|
||||||
|
},
|
||||||
|
"validation_error": {
|
||||||
|
"name": "Validation Error",
|
||||||
|
"type": "string",
|
||||||
|
"default": et2_no_init,
|
||||||
|
"description": "Used internally to store the validation error that came from the server."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -70,7 +76,6 @@ var et2_inputWidget = et2_valueWidget.extend(et2_IInput, {
|
|||||||
|
|
||||||
this._oldValue = "";
|
this._oldValue = "";
|
||||||
this._labelContainer = null;
|
this._labelContainer = null;
|
||||||
this._widgetPlaceholder = null;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
destroy: function() {
|
destroy: function() {
|
||||||
@ -83,34 +88,23 @@ var et2_inputWidget = et2_valueWidget.extend(et2_IInput, {
|
|||||||
this._super.apply(this, arguments);
|
this._super.apply(this, arguments);
|
||||||
|
|
||||||
this._labelContainer = null;
|
this._labelContainer = null;
|
||||||
this._widgetPlaceholder = null;
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the validation errors from the server
|
||||||
|
*/
|
||||||
|
transformAttributes: function(_attrs) {
|
||||||
|
this._super.apply(this, arguments);
|
||||||
|
|
||||||
|
// Check whether an validation error entry exists
|
||||||
|
var val = this.getArrayMgr("validation_errors").getValueForID(this.id);
|
||||||
|
if (val)
|
||||||
|
{
|
||||||
|
_attrs["validation_error"] = val;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
attachToDOM: function() {
|
attachToDOM: function() {
|
||||||
if (this._labelContainer)
|
|
||||||
{
|
|
||||||
// Get the DOM Node without the labelContainer - that's why null is
|
|
||||||
// passed here.
|
|
||||||
var node = this.getDOMNode(null);
|
|
||||||
|
|
||||||
if (node)
|
|
||||||
{
|
|
||||||
// Recreate the widget placeholder and return, as the set_label
|
|
||||||
// function will call attachToDOM again
|
|
||||||
if (!this._widgetPlaceholder)
|
|
||||||
{
|
|
||||||
this.set_label(this.label);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert the widget at the position of the placeholder
|
|
||||||
this._labelContainer.replaceChild(node, this._widgetPlaceholder);
|
|
||||||
|
|
||||||
// Set the widgetPlaceholder to null
|
|
||||||
this._widgetPlaceholder = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var node = this.getInputNode();
|
var node = this.getInputNode();
|
||||||
if (node)
|
if (node)
|
||||||
{
|
{
|
||||||
@ -121,14 +115,14 @@ var et2_inputWidget = et2_valueWidget.extend(et2_IInput, {
|
|||||||
|
|
||||||
this._super.apply(this,arguments);
|
this._super.apply(this,arguments);
|
||||||
|
|
||||||
$j(this.getInputNode()).attr("novalidate","novalidate"); // Stop browser from getting involved
|
// $j(this.getInputNode()).attr("novalidate","novalidate"); // Stop browser from getting involved
|
||||||
$j(this.getInputNode()).validator();
|
// $j(this.getInputNode()).validator();
|
||||||
},
|
},
|
||||||
|
|
||||||
detatchFromDOM: function() {
|
detatchFromDOM: function() {
|
||||||
if(this.getInputNode()) {
|
// if(this.getInputNode()) {
|
||||||
$j(this.getInputNode()).data("validator").destroy();
|
// $j(this.getInputNode()).data("validator").destroy();
|
||||||
}
|
// }
|
||||||
this._super.apply(this,arguments);
|
this._super.apply(this,arguments);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -171,14 +165,10 @@ var et2_inputWidget = et2_valueWidget.extend(et2_IInput, {
|
|||||||
},
|
},
|
||||||
|
|
||||||
set_label: function(_value) {
|
set_label: function(_value) {
|
||||||
// Copy the given value
|
// Abort if ther was no change in the label
|
||||||
this.label = _value;
|
if (_value == this.label)
|
||||||
|
|
||||||
// Detach the current element from the DOM
|
|
||||||
var attached = this.isAttached();
|
|
||||||
if (attached)
|
|
||||||
{
|
{
|
||||||
this.detatchFromDOM();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_value)
|
if (_value)
|
||||||
@ -186,46 +176,49 @@ var et2_inputWidget = et2_valueWidget.extend(et2_IInput, {
|
|||||||
// Create the label container if it didn't exist yet
|
// Create the label container if it didn't exist yet
|
||||||
if (this._labelContainer == null)
|
if (this._labelContainer == null)
|
||||||
{
|
{
|
||||||
this._labelContainer = document.createElement("label");
|
this._labelContainer = $j(document.createElement("label"))
|
||||||
this._labelContainer.setAttribute("class", "et2_label");
|
.addClass("et2_label");
|
||||||
|
this.getSurroundings().insertDOMNode(this._labelContainer[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the label container.
|
// Clear the label container.
|
||||||
for (;this._labelContainer.childNodes.length > 0;)
|
this._labelContainer.empty();
|
||||||
{
|
|
||||||
this._labelContainer.removeChild(this._labelContainer.childNodes[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the placeholder element
|
// Create the placeholder element and set it
|
||||||
this._widgetPlaceholder = document.createElement("span");
|
var ph = document.createElement("span");
|
||||||
|
this.getSurroundings().setWidgetPlaceholder(ph);
|
||||||
|
|
||||||
// Split the label at the "%s"
|
// Split the label at the "%s"
|
||||||
var parts = et2_csvSplit(_value, 2, "%s");
|
var parts = et2_csvSplit(_value, 2, "%s");
|
||||||
|
|
||||||
// Create the content of the label container
|
// Update the content of the label container
|
||||||
for (var i = 0; i < parts.length; i++)
|
for (var i = 0; i < parts.length; i++)
|
||||||
{
|
{
|
||||||
if (parts[i])
|
if (parts[i])
|
||||||
{
|
{
|
||||||
this._labelContainer.appendChild(document.createTextNode(parts[i]));
|
this._labelContainer.append(document.createTextNode(parts[i]));
|
||||||
}
|
}
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
{
|
{
|
||||||
this._labelContainer.appendChild(this._widgetPlaceholder);
|
this._labelContainer.append(ph);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Delete the labelContainer from the surroundings object
|
||||||
|
if (this._labelContainer)
|
||||||
|
{
|
||||||
|
this.getSurroundings().deleteDOMNode(this._labelContainer[0]);
|
||||||
|
}
|
||||||
this._labelContainer = null;
|
this._labelContainer = null;
|
||||||
this._widgetPlaceholder = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attach the current element to the DOM again
|
// Update the surroundings in order to reflect the change in the label
|
||||||
if (attached)
|
this.getSurroundings().update();
|
||||||
{
|
|
||||||
this.attachToDOM();
|
// Copy the given value
|
||||||
}
|
this.label = _value;
|
||||||
},
|
},
|
||||||
|
|
||||||
set_required: function(_value) {
|
set_required: function(_value) {
|
||||||
@ -241,13 +234,21 @@ var et2_inputWidget = et2_valueWidget.extend(et2_IInput, {
|
|||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getDOMNode: function(_sender) {
|
set_validation_error: function(_value) {
|
||||||
if (_sender == this && this._labelContainer)
|
var node = this.getInputNode();
|
||||||
|
if (node)
|
||||||
{
|
{
|
||||||
return this._labelContainer;
|
if (_value === false)
|
||||||
|
{
|
||||||
|
this.hideMessage();
|
||||||
|
$j(node).removeClass("invalid");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.showMessage(_value, "validation_error");
|
||||||
|
$j(node).addClass("invalid");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._super.apply(this, arguments);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getInputNode: function() {
|
getInputNode: function() {
|
||||||
|
@ -585,77 +585,6 @@ var et2_widget = Class.extend({
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetches all input element values and returns them in an associative
|
|
||||||
* array. Widgets which introduce namespacing can use the internal _target
|
|
||||||
* parameter to add another layer.
|
|
||||||
*/
|
|
||||||
getValues: function() {
|
|
||||||
var result = {};
|
|
||||||
|
|
||||||
// Iterate over the widget tree
|
|
||||||
this.iterateOver(function(_widget) {
|
|
||||||
|
|
||||||
// The widget must have an id to be included in the values array
|
|
||||||
if (_widget.id == "")
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the path to the node we have to store the value at
|
|
||||||
var path = _widget.getArrayMgr("content").getPath();
|
|
||||||
|
|
||||||
// check if id contains a hierachical name, eg. "button[save]"
|
|
||||||
var id = _widget.id;
|
|
||||||
if (_widget.id.indexOf('[') != -1)
|
|
||||||
{
|
|
||||||
var parts = _widget.id.replace(/]/g,'').split('[');
|
|
||||||
id = parts.pop();
|
|
||||||
path = path.concat(parts);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the _target variable to that node
|
|
||||||
var _target = result;
|
|
||||||
for (var i = 0; i < path.length; i++)
|
|
||||||
{
|
|
||||||
// Create a new object for not-existing path nodes
|
|
||||||
if (typeof _target[path[i]] == "undefined")
|
|
||||||
{
|
|
||||||
_target[path[i]] = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check whether the path node is really an object
|
|
||||||
if (_target[path[i]] instanceof Object)
|
|
||||||
{
|
|
||||||
_target = _target[path[i]];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
et2_debug("error", "ID collision while writing at path " +
|
|
||||||
"node '" + path[i] + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check whether the entry is really undefined
|
|
||||||
if (typeof _target[id] != "undefined")
|
|
||||||
{
|
|
||||||
et2_debug("error", _widget, "Overwriting value of '" + _widget.id +
|
|
||||||
"', id exists twice!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store the value of the widget and reset its dirty flag
|
|
||||||
var value = _widget.getValue();
|
|
||||||
if (value !== null)
|
|
||||||
{
|
|
||||||
_target[id] = value;
|
|
||||||
}
|
|
||||||
_widget.resetDirty();
|
|
||||||
|
|
||||||
}, this, et2_IInput);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets all array manager objects - this function can be used to set the
|
* Sets all array manager objects - this function can be used to set the
|
||||||
* root array managers of the container object.
|
* root array managers of the container object.
|
||||||
|
@ -166,7 +166,7 @@ etemplate2.prototype.submit = function()
|
|||||||
if(!valid) return false;*/
|
if(!valid) return false;*/
|
||||||
|
|
||||||
// Get the form values
|
// Get the form values
|
||||||
var values = this.widgetContainer.getValues();
|
var values = this.getValues(this.widgetContainer);
|
||||||
|
|
||||||
// Trigger the submit event
|
// Trigger the submit event
|
||||||
if (this.fireEvent("submit", [values]))
|
if (this.fireEvent("submit", [values]))
|
||||||
@ -184,6 +184,78 @@ etemplate2.prototype.submit = function()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all input element values and returns them in an associative
|
||||||
|
* array. Widgets which introduce namespacing can use the internal _target
|
||||||
|
* parameter to add another layer.
|
||||||
|
*/
|
||||||
|
etemplate2.prototype.getValues = function(_root)
|
||||||
|
{
|
||||||
|
var result = {};
|
||||||
|
|
||||||
|
// Iterate over the widget tree
|
||||||
|
_root.iterateOver(function(_widget) {
|
||||||
|
|
||||||
|
// The widget must have an id to be included in the values array
|
||||||
|
if (_widget.id == "")
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the path to the node we have to store the value at
|
||||||
|
var path = _widget.getArrayMgr("content").getPath();
|
||||||
|
|
||||||
|
// check if id contains a hierachical name, eg. "button[save]"
|
||||||
|
var id = _widget.id;
|
||||||
|
if (_widget.id.indexOf('[') != -1)
|
||||||
|
{
|
||||||
|
var parts = _widget.id.replace(/]/g,'').split('[');
|
||||||
|
id = parts.pop();
|
||||||
|
path = path.concat(parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the _target variable to that node
|
||||||
|
var _target = result;
|
||||||
|
for (var i = 0; i < path.length; i++)
|
||||||
|
{
|
||||||
|
// Create a new object for not-existing path nodes
|
||||||
|
if (typeof _target[path[i]] == "undefined")
|
||||||
|
{
|
||||||
|
_target[path[i]] = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether the path node is really an object
|
||||||
|
if (_target[path[i]] instanceof Object)
|
||||||
|
{
|
||||||
|
_target = _target[path[i]];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
et2_debug("error", "ID collision while writing at path " +
|
||||||
|
"node '" + path[i] + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether the entry is really undefined
|
||||||
|
if (typeof _target[id] != "undefined")
|
||||||
|
{
|
||||||
|
et2_debug("error", _widget, "Overwriting value of '" + _widget.id +
|
||||||
|
"', id exists twice!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the value of the widget and reset its dirty flag
|
||||||
|
var value = _widget.getValue();
|
||||||
|
if (value !== null)
|
||||||
|
{
|
||||||
|
_target[id] = value;
|
||||||
|
}
|
||||||
|
_widget.resetDirty();
|
||||||
|
|
||||||
|
}, this, et2_IInput);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an callback function to the given event slot
|
* Adds an callback function to the given event slot
|
||||||
*
|
*
|
||||||
|
@ -74,6 +74,9 @@ var timesheet_data = {
|
|||||||
"tabs":{
|
"tabs":{
|
||||||
"customfields":true
|
"customfields":true
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"validation_errors": {
|
||||||
|
"ts_title": "Please enter some meaningful title here!"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BIN
etemplate/js/test/gfx/error.png
Normal file
BIN
etemplate/js/test/gfx/error.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 701 B |
BIN
etemplate/js/test/gfx/hint.png
Normal file
BIN
etemplate/js/test/gfx/hint.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 778 B |
BIN
etemplate/js/test/gfx/tick.png
Normal file
BIN
etemplate/js/test/gfx/tick.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 537 B |
@ -219,8 +219,8 @@ input[required] {
|
|||||||
background-color: #ffffd0;
|
background-color: #ffffd0;
|
||||||
}
|
}
|
||||||
input.invalid {
|
input.invalid {
|
||||||
border-style: dotted;
|
border: 1px solid #a6261d;
|
||||||
border-color: red;
|
background-color: #faecec;
|
||||||
}
|
}
|
||||||
.error {
|
.error {
|
||||||
-moz-border-radius: 0 4px 4px 0;
|
-moz-border-radius: 0 4px 4px 0;
|
||||||
@ -268,3 +268,52 @@ label input, label span, label div, label select, label textarea {
|
|||||||
margin-right: 1ex;
|
margin-right: 1ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message styles
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Style used for a generic message (such as success messages or validation errors) */
|
||||||
|
.message {
|
||||||
|
display: block;
|
||||||
|
border: 1px solid gray;
|
||||||
|
padding: 3px 3px 3px 22px;
|
||||||
|
margin: 5px 0px 5px 0px;
|
||||||
|
-webkit-border-radius: 3px;
|
||||||
|
-moz-border-radius: 3px;
|
||||||
|
border-radius: 3px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: 3px center;
|
||||||
|
clear: left;
|
||||||
|
max-width: 500px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message.floating {
|
||||||
|
display: inline;
|
||||||
|
margin: 0px 5px 0px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message.validation_error {
|
||||||
|
color: #a93030;
|
||||||
|
font-style: italic;
|
||||||
|
background-color: #f3d4d0;
|
||||||
|
border-color: #a93030;
|
||||||
|
background-image:url(gfx/error.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
.message.success {
|
||||||
|
font-style: normal;
|
||||||
|
background-color: #e5f3d0;
|
||||||
|
color: #98a930;
|
||||||
|
border-color: #9ea930;
|
||||||
|
background-image:url(gfx/tick.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
.message.hint {
|
||||||
|
font-style: normal;
|
||||||
|
background-color: #d9e2ed;
|
||||||
|
border-color: #56729a;
|
||||||
|
color: #56729a;
|
||||||
|
background-image:url(gfx/hint.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user