From 89230b86cf2bf04fd0d1d706015a8d572a331f21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20St=C3=B6ckel?= Date: Fri, 12 Aug 2011 15:26:08 +0000 Subject: [PATCH] Added functions to expand names and a basic implementation for 'disabled' --- etemplate/js/et2_DOMWidget.js | 27 ++++ etemplate/js/et2_contentArrayMgr.js | 170 +++++++++++++++++++- etemplate/js/et2_inputWidget.js | 17 +- etemplate/js/et2_widget.js | 24 ++- etemplate/js/test/et2_test_expressions.json | 4 + etemplate/js/test/et2_test_expressions.xet | 6 + etemplate/js/test/test_xml.html | 2 + 7 files changed, 246 insertions(+), 4 deletions(-) create mode 100644 etemplate/js/test/et2_test_expressions.json create mode 100644 etemplate/js/test/et2_test_expressions.xet diff --git a/etemplate/js/et2_DOMWidget.js b/etemplate/js/et2_DOMWidget.js index e7eaa515ba..5071719d0e 100644 --- a/etemplate/js/et2_DOMWidget.js +++ b/etemplate/js/et2_DOMWidget.js @@ -46,6 +46,15 @@ var et2_IDOMNode = new Interface({ */ var et2_DOMWidget = et2_widget.extend(et2_IDOMNode, { + attributes: { + "disabled": { + "name": "Visible", + "type": "boolean", + "description": "Defines whether this widget is visible.", + "default": false + } + }, + /** * When the DOMWidget is initialized, it grabs the DOM-Node of the parent * object (if available) and passes it to its own "createDOMNode" function @@ -58,6 +67,8 @@ var et2_DOMWidget = et2_widget.extend(et2_IDOMNode, { "parent": null }; + this.disabled = false; + // Call the inherited constructor this._super.apply(this, arguments); }, @@ -178,6 +189,22 @@ var et2_DOMWidget = et2_widget.extend(et2_IDOMNode, { node.removeAttribute("id"); } } + }, + + set_disabled: function(_value) { + if (this.node) + { + this.diabled = _value; + + if (_value) + { + $j(this.node).hide(); + } + else + { + $j(this.node).show(); + } + } } }); diff --git a/etemplate/js/et2_contentArrayMgr.js b/etemplate/js/et2_contentArrayMgr.js index 20ce93fd95..e6cb50759d 100644 --- a/etemplate/js/et2_contentArrayMgr.js +++ b/etemplate/js/et2_contentArrayMgr.js @@ -24,7 +24,33 @@ function et2_contentArrayMgr(_data, _parentMgr) this.parentMgr = _parentMgr; // Hold a reference to the data + if (typeof _data == "undefined" || !_data) + { + et2_debug("error", "Invalid data passed to content array manager!"); + _data = {}; + } + this.data = _data; + + // Holds information about the current perspective + this.perspectiveData = { + "key": null, + "col": 0, + "row": 0 + } +} + +/** + * Returns the root content array manager object + */ +et2_contentArrayMgr.prototype.getRoot = function() +{ + if (this.parentMgr != null) + { + return this.parentMgr.getRoot(); + } + + return this; } et2_contentArrayMgr.prototype.getValueForID = function(_id) @@ -37,8 +63,148 @@ et2_contentArrayMgr.prototype.getValueForID = function(_id) return null; } -et2_contentArrayMgr.prototype.openPerspective = function(_rootId) +/** + * Get array entry is the equivalent to the boetemplate get_array function. + * It returns a reference to the (sub) array with the given key. This also works + * for keys using the ETemplate referencing scheme like a[b][c] + * + * @param _key is the string index, may contain sub-indices like a[b] + * @param _referenceInto if true none-existing sub-arrays/-indices get created + * to be returned as reference, else false is returned. Defaults to false + * @param _skipEmpty returns false if _key is not present in this content array. + * Defaults to false. + */ +et2_contentArrayMgr.prototype.getEntry = function(_key, _referenceInto, + _skipEmpty) { - return new et2_contentArrayMgr(this._data[_rootId], this); + if (typeof _referenceInto == "undefined") + { + _referenceInto = false; + } + + if (typeof _skipEmpty == "undefined") + { + _skipEmpty = false; + } + + // Parse the given key by removing the "]"-chars and splitting at "[" + var indexes = _key.replace(/]/g,'').split('['); + + var entry = this.data; + for (var i = 0; i < indexes.length; i++) + { + // Abort if the current entry is not an object (associative array) and + // we should descend further into it. + var isObject = entry instanceof Object; + if (!isObject && !_referenceInto) + { + return false; + } + + // Check whether the entry actually exists + var idx = indexes[i]; + if (_skipEmpty && (!isObject || typeof entry[idx] == "undefined")) + { + return false; + } + + entry = entry[idx]; + } + + return entry; +} + +/** + * Equivaltent to the boetemplate::expand_name function. + * + * Expands variables inside the given identifier to their values inside the + * content array. + */ +et2_contentArrayMgr.prototype.expandName = function(_ident) +{ + // Check whether the identifier refers to an index in the content array + var is_index_in_content = _ident.charAt(0) == '@'; + + // Check whether "$" occurs in the given identifier + var pos_var = _ident.indexOf('$'); + if (pos_var >= 0) + { + // TODO + } + + if (is_index_in_content) + { + // If an additional "@" is specified, this means that we have to return + // the entry from the root element + if (_ident.charAt(1) == '@') + { + _ident = this.getRoot().getEntry(_ident.substr(2)); + } + + _ident = this.getEntry(_ident.substr(1)); + } + + return _ident; +} + +et2_contentArrayMgr.prototype.parseBoolExpression = function(_expression) +{ + // If the first char of the expression is a '!' this means, that the value + // is to be negated. + if (_expression.charAt(0) == '!') + { + return !this.parseBoolExpression(_expression.substr(1)); + } + + // Split the expression at a possible "=" + var parts = _expression.split('='); + + // Expand the first value + var val = this.expandName(parts[0]); + + // If a second expression existed, test that one + if (typeof parts[1] != "undefined") + { + // Expand the second value + var checkVal = this.expandName(parts[1]); + + // Values starting with / are treated as regular expression. It is + // checked whether the first value matches the regular expression + if (checkVal.charAt(0) == '/') + { + return (new RegExp(checkVal.substr(1, checkVal.length - 2))) + .match(val) ? true : false; + } + + // Otherwise check for simple equality + return val == checkVal; + } + + return val != '' && (typeof val != "string" || val.toLowerCase() != "false"); +} + +et2_contentArrayMgr.prototype.openPerspective = function(_root, _col, _row) +{ + // Get the root node + var root = typeof _root == "string" ? this.data[_root] : + (_root == null ? this.data : _root); + + // Create a new content array manager with the given root + var mgr = new et2_contentArrayMgr(root, this); + + // Set the root key + if (typeof _root == "string") + { + mgr.perspectiveData.key == _root; + } + + // Set the _col and _row parameter + if (typeof _col != "undefined" && typeof _row != "undefined") + { + mgr.perspectiveData.col = _col; + mgr.perspectiveData.row = _row; + } + + return mgr; } diff --git a/etemplate/js/et2_inputWidget.js b/etemplate/js/et2_inputWidget.js index 00553f9f02..aa11b061af 100644 --- a/etemplate/js/et2_inputWidget.js +++ b/etemplate/js/et2_inputWidget.js @@ -71,8 +71,23 @@ var et2_inputWidget = et2_baseWidget.extend(et2_IInput, { }, set_id: function(_value) { - this._super.apply(this, arguments); + this.id = _value; + // Set the id of the input node + var node = this.getInputNode(); + if (node) + { + if (_value != "") + { + node.setAttribute("id", _value); + } + else + { + node.removeAttribute("id"); + } + } + + // Set the value for this element var mgr = this.getContentMgr(); if (_value != '' && mgr != null) { diff --git a/etemplate/js/et2_widget.js b/etemplate/js/et2_widget.js index 8156c4385d..efd1fab72f 100644 --- a/etemplate/js/et2_widget.js +++ b/etemplate/js/et2_widget.js @@ -381,6 +381,7 @@ var et2_widget = Class.extend({ 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 @@ -393,7 +394,28 @@ var et2_widget = Class.extend({ } else { - this.setAttribute(_attrs[i].name, _attrs[i].value); + var attrName = _attrs[i].name; + var attrValue = _attrs[i].value; + + if (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 = this.getContentMgr() + .parseBoolExpression(attrValue); + } + else + { + attrValue = this.getContentMgr().expandName(attrValue); + } + } + + // Set the attribute + this.setAttribute(attrName, attrValue); } } }, diff --git a/etemplate/js/test/et2_test_expressions.json b/etemplate/js/test/et2_test_expressions.json new file mode 100644 index 0000000000..fcdf1b47c7 --- /dev/null +++ b/etemplate/js/test/et2_test_expressions.json @@ -0,0 +1,4 @@ +var expression_test_data = { + "display_text": "true" +}; + diff --git a/etemplate/js/test/et2_test_expressions.xet b/etemplate/js/test/et2_test_expressions.xet new file mode 100644 index 0000000000..eb796e1a03 --- /dev/null +++ b/etemplate/js/test/et2_test_expressions.xet @@ -0,0 +1,6 @@ + + + + diff --git a/etemplate/js/test/test_xml.html b/etemplate/js/test/test_xml.html index 902aa27392..b8bd833604 100644 --- a/etemplate/js/test/test_xml.html +++ b/etemplate/js/test/test_xml.html @@ -21,6 +21,7 @@ +