﻿/// <summary>The root object for the ajaxForms functionality.</summary>
var ajaxForms = new Object();

// ----- ajaxForms implementation -----


///<summary>This method clears the values of the html elements of type INPUT, TEXTAREA and SELECT that have a name.</summary>
///<param name="obj">A reference or an id of the html object containing the ajax form UI.</param>
ajaxForms.clearData = function(obj) {
  var n, aList, elem;
  
  obj = ajaxForms._getFormObj("ajaxForms.clearData", obj);
  elem = document.getElementById("pageheader");
  if (elem) {
    elem.innerHTML = "<h1>" + elem.innerText.split(":")[0] + ": </h1>";
  }
  // clear the text of fields and uncheck checkboxes.
  aList = obj.getElementsByTagName("INPUT");
  for (n = 0; n < aList.length; n++) {
    if ((aList[n].name != null) && (aList[n].name != "")) {
      if (aList[n].type == "text") {
        aList[n].value = "";
      } else if (aList[n].type == "checkbox") {
        aList[n].checked = false;
      } // if
    } // if
  } // for

  // clear the text of textareas
  aList = obj.getElementsByTagName("TEXTAREA");
  for (n = 0; n < aList.length; n++) {
    if ((aList[n].name != null) && (aList[n].name != "")) {
      aList[n].value = "";
    } // if
  } // for

  // because there is no real clear with select objects, the select is reset to the default-value
  aList = obj.getElementsByTagName("SELECT");
  for (n = 0; n < aList.length; n++) {
    if ((aList[n].name != null) && (aList[n].name != "")) {
      aList[n].value = "";
      
      for (o = 0; o < aList[n].options.length; o++) {
        if (aList[n].options[o].defaultSelected) {
          aList[n].selectedIndex = o;
          break;
        }
      } // for
    }
  } // for
  
  // more resetting
  aList = obj.getElementsByTagName("IMG");
  for (n = 0; n < aList.length; n++) {
    if ((aList[n].className != null) && (aList[n].className != "" && aList[n].className == "THUMB")) {
      aList[n].src = "../images/cust/boschpt/thumbs/default.gif";
    } // if
  } // for
  
  elem = document.getElementById("matrix");
  if (elem != null && elem.id != "" && elem.id == "matrix") {
    elem.style.display = "none";
  }

  aList = obj.getElementsByTagName("IFRAME");
  for (n = 0; n < aList.length; n++) {
    if ((aList[n].name != null) && (aList[n].name != "")) {
      aList[n].src = "about:blank";
    } // if
  } // for
  
  try {
    var allfctions = document.getElementById("ctl00_ContentPlaceHolder1_Menue").getElementsByTagName("IMG");
    for (var i = 1; i < allfctions.length; i++) {
      if (allfctions[i].id != "add_img" && allfctions[i].id != "list_img") {
        allfctions[i].style.display = "none";
      }
    } // for
    allfctions = document.getElementById("ctl00_ContentPlaceHolder1_Menue").getElementsByTagName("LABEL");
    for (var i = 1; i < allfctions.length; i++) {
      if (allfctions[i].id != "add_lbl" && allfctions[i].id != "list_lbl") {
        allfctions[i].style.display = "none";
      }
    } // for
  } catch(e) {
  }
  ajaxForms.clearErrors(obj);
} // ajaxForms.clearData


///<summary>This method clears the values of the html elements of type INPUT, TEXTAREA and SELECT that have a name.</summary>
///<param name="obj">A reference or an id of the html object containing the ajax form UI.</param>
ajaxForms.resetData = function(obj) {
  var n, aList;
  
  obj = ajaxForms._getFormObj("ajaxForms.resetData", obj);

  // reset text & checked
  aList = obj.getElementsByTagName("INPUT");
  for (n = 0; n < aList.length; n++) {
    if ((aList[n].name != null) && (aList[n].name != "")) {
      if (aList[n].type == "text") {
        aList[n].value = aList[n].defaultValue;
      } else if (aList[n].type == "checkbox") {
        aList[n].checked = aList[n].defaultSelected;
      } // if
    } // if
  } // for

  // reset text
  aList = obj.getElementsByTagName("TEXTAREA");
  for (n = 0; n < aList.length; n++) {
    if ((aList[n].name != null) && (aList[n].name != "")) {
      aList[n].value = aList[n].defaultValue;
    } // if
  } // for

  // reset selected
  aList = obj.getElementsByTagName("SELECT");
  for (n = 0; n < aList.length; n++) {
    if ((aList[n].name != null) && (aList[n].name != ""))
      for (o = 0; o < aList[n].options.length; o++) {
        if (aList[n].options[o].defaultSelected) {
          aList[n].selectedIndex = o;
          break;
        } // if
      } // for
  } // for

  ajaxForms.clearErrors(obj);
} // ajaxForms.resetData


///<summary>Parse an exception for an ArgumentException and set the error annotations</summary>
///<param name="ex">An exception object.</param>
///<param name="obj">A reference or an id of the html object containing the ajax form UI.</param>
ajaxForms.processException = function(ex, obj) {
  var txt = ex.description;
  if ((ex.message == "soap:Server") && (txt != null) && (txt.indexOf("System.ArgumentException: ") > 0)) {
    obj = ajaxForms._getFormObj("ajaxForms.processException", obj);
  
    txt = txt.substr(txt.indexOf("System.ArgumentException: ") + 26).split('\n');
    var param = txt[1].substr(txt[1].indexOf(':')+2);
    
    var aList = document.getElementsByTagName("SPAN");
    for (var n = 0; n < aList.length; n++) {
      if ((aList[n].className == "AJAXFORMEXCEPTION") && (aList[n].getAttribute("name") == param)) {
        aList[n].style.display = "inline";
        aList[n].innerText = txt[0]; // IE
        aList[n].textContent = txt[0]; // FF
        break;
      } // if
    } // for
  } else {
    proxies.alertException(ex);
  } // if
}


///<summary>This method clears the error annotations of the html elements of type SPAN
///that have the className AJAXFORMEXCEPTION.</summary>
///<param name="obj">A reference or an id of the html object containing the ajax form UI.</param>
ajaxForms.clearErrors = function(obj) {
  var n;
  var aList = document.getElementsByTagName("SPAN");
  for (n = 0; n < aList.length; n++) {
    if (aList[n].className == "AJAXFORMEXCEPTION") {
      aList[n].style.display = "none";
      aList[n].innerText = ""; // IE
      aList[n].textContent = ""; // FF
    } // if
  } // for
} // clearErrors


///<summary>private method for getting the html object containing the ajax form UI.</summary>
// txt the name of the public method
///<param name="obj">A reference or an id of the html object containing the ajax form UI.</param>
ajaxForms._getFormObj = function(txt, obj) {
  if (obj == null)
    throw new Error(txt + ": Argument 'obj' must be set.");

  // maybe an id of an object was passed.
  if (obj.constructor == String)
    obj = document.getElementById(obj);
  if (obj == null)
    throw new Error(txt + ": Argument 'obj' is unknown.");
  return(obj);
} // _getFormObj


///<summary>Get a browser specific implementation of the XMLDOM object, containing a XML document.</summary>
///<param name="xmlText">the xml document as string.</param>
ajaxForms._getXMLDOM = function (xmlText) {
  var obj = null;

  if (typeof(DOMParser) != "undefined") {
    // Gecko / Mozilla / Firefox
    var parser = new DOMParser();
    obj = parser.parseFromString(xmlText, "text/xml");

  } else {    
    // IE
    try {
      obj = new ActiveXObject("MSXML2.DOMDocument");
    } catch (e) { }

    if (obj == null) {
      try {
        obj = new ActiveXObject("Microsoft.XMLDOM");
      } catch (e) { }
    } // if
  
    if (obj != null) {
      obj.async = false;
      obj.validateOnParse = false;
    } // if
    obj.loadXML(xmlText);
  } // if
  return(obj);
} // _getXMLDOM


// ----- formatting functions -----
// These functions are used for formatting values (number, dates...) to human readable strings
// with the typical national language specific notation.
// current: German: de

var nls = {
  string: {
    title: "Geben Sie einen Wert ein.",
    toString: function(v) { return(v); },
    toValue: function(s) { return(s); }
    }, // string
    

  int: {
    title: "Geben Sie einen ganzzahligen Wert ein.",
    keys: "-0123456789",
    toString: function(v) { return(v); },
    toValue: function(s) { return(s); }
    }, // int

  
  decimal: {
    title: "Geben Sie einen Wert mit optionalen Nachkommastellen in der Form '123.456,78' ein.",
    keys: ",-0123456789", mapkeys: ". ",
    toString: function(v, l) {
      var s = String(v);
      var p = parseInt(l); // CKE 12.08.2008

      // adjust precission digits
      if (p == null) {
      } else if (p <= 0) {
        s = s.replace(/\..*$/g, ''); // remove precission digits
      } else { 
        if (s.indexOf('.') < 0)
          s = s + '.';
        s = s + '0000000000';
        s = s.substr(0, s.indexOf('.') + p + 1);
      } // if

      s = s.replace(/\./g, ','); // use decimal komma
      s = s.replace(/(\d{1,})(\d{3})(\d{3})(,|$)/, "$1.$2.$3$4"); // use decimal points
      s = s.replace(/(\d{1,})(\d{3})(,|$)/, "$1.$2$3"); // use decimal points
      return(s); 
    },
    
    toValue: function(s, p) { 
      s = String(s);
      s = s.replace(/\./g, ''); // use decimal komma
      s = s.replace(/\,/g, '.'); // use decimal points
      return(s);
    }
  }, // decimal


  date: {
    title: "Geben Sie ein Datum in der Form 'tt.mm.jjjj' ein.",
    keys: ".0123456789", mapkeys: ",",
    toString: function(v) {
      var s = "";
      if ((v != null) && (v.constructor == Date))
        s = nls.d2(v.getDate()) + "." + nls.d2(v.getMonth()+1) + "." + v.getFullYear();
      return(s);
      },

    toValue: function(s) {
      var d = null;
      if ((s == null) || (s == "")) {
        return(d);
      } else if (s == "*") {
        d = new Date();
      } else if (s.match(/^\d+\.\d+\.\d+$/)) {
        s = s.split('.');
        d = new Date(parseInt(s[2], 10), parseInt(s[1], 10)-1, parseInt(s[0], 10), 0, 0, 0);
      } else if (s.match(/^\d+\.\d+\.?$/)) {
        s = s.split('.');
        d = new Date((new Date().getFullYear()), parseInt(s[1], 10)-1, parseInt(s[0], 10), 0, 0, 0);
      } else if (s.match(/^\d{4}$/)) {
        d = new Date((new Date().getFullYear()), parseInt(s.substr(2, 2), 10)-1, parseInt(s.substr(0, 2), 10), 0, 0, 0);
      } else if (s.match(/^\d{6}$/)) {
        d = new Date(parseInt(s.substr(4, 2), 10), parseInt(s.substr(2, 2), 10)-1, parseInt(s.substr(0, 2), 10), 0, 0, 0);
      } else if (s.match(/^\d{8}$/)) {
        d = new Date(parseInt(s.substr(4, 4), 10), parseInt(s.substr(2, 2), 10)-1, parseInt(s.substr(0, 2), 10), 0, 0, 0);
      }
      return(d);
      },
    firstDayOfWeek: 1, // mo
    weekdayName: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"],
    monthName: ["Jan", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"]
  }, // date

  
  // format a number using 2 characters min. with leading 0s
  d2: function(d) {
    d = String(d);
    if (d.length == 0)
      d = "00";
    else if (d.length == 1)
      d = "0" + d;
    return(d);
  } // d2
} // nls


// ----- End -----


// IMS-Extension

ajaxForms.rowscount = 0;
ajaxForms._tagIn = new Array(); // in/out elements: INPUT, TEXTAREA, SELECT
ajaxForms._tagOut = new Array(); // out elements: SPAN, DIV, TD
ajaxForms._types = null;
ajaxForms._nulls = null;
ajaxForms._lens = null;

  /**
   * fill all nested objects with values from the specified XML source.
   * @xdata xml of the select
   * @rootfrm data bound form object
   */
ajaxForms.readData = function (xdata, rootfrm) 
{
//  var _tagA      = new Array(); // Hyperlinks
//  var _tagIMG    = new Array(); // Images
//  var _tagFRAME  = new Array(); // iFrames

//  var _chars; // characters allowed for input in current field
//  var _WebAppRoot; // the root folder url of the current web application

  if (xdata && rootfrm) {
    rootfrm = document.getElementById(rootfrm);
    ajaxForms._analyseForm(rootfrm);
    ajaxForms._readData(xdata, rootfrm);
  }
  
  return ajaxForms.rowscount;
} // readData


/** 
  analyse all objects (recursive) and find out, if they are data-bound.
  @param root paremt of the analysed objects. 
  */
ajaxForms._analyseForm = function(root)
{
  var node = root.firstChild;
  var s;
  
  while (node != null) {
    s = node.className;
    if ((node.name != null) && (node.name != "")) {
      s = node.tagName;
      if ((s == "INPUT") ||(s == "TEXTAREA") || (s == "SELECT")) {
        ajaxForms._tagIn[ajaxForms._tagIn.length] = node;
      } else if ((s == "DIV") && ((node.className == "IMSHTMLTEXT") || (node.className == "IMSDATAPART"))) {
        ajaxForms._tagIn[ajaxForms._tagIn.length] = node;
      } else if ((s == "SPAN") || (s == "TD")) {
        ajaxForms._tagOut[ajaxForms._tagOut.length] = node;
        // not _analyseForm(node), because nested elements get destroyed on setData !
      } else {
        ajaxForms._analyseForm(node);
      }
    } else {
      ajaxForms._analyseForm(node);
    }
    node = node.nextSibling;
  } // while
} // _analyseForm
  
  
/**
  * fill all nested objects with values from the specified XML source.
  * @xdata xml of the select
  * @rootfrm data bound form object
  */
ajaxForms._readData = function(xdata, rootfrm)
{
  var zRow = null;    // XML node of the record (z:row)
  xdata = ajaxForms._getXMLDOM(xdata);
  
  if (xdata == null) {
    xdata = xmlRoot;
  }
  xmlRoot = xdata;

  if (xdata != null) {
    ajaxForms._prepareTypes(xdata.selectSingleNode(".//s:Schema"));
    zRow = xdata.selectSingleNode(".//z:row | .//row");
    
    if (zRow == null) {
      if (xdata.nodeType == 9) {
        zRow = xdata.createElement("z:row");
      } else {
        zRow = xdata.ownerDocument.createElement("z:row");
      }
    }
    ajaxForms._fillForm(xdata, rootfrm);  // fill into the form
  }
  if (rootfrm.getAttribute("onFormSet") != null) { // FF
    //alert(rootfrm.onFormSet);
    try {
      eval("window." + rootfrm.getAttribute("onFormSet"))(rootfrm);
    } catch(e) {}
  }
  dbfo.checkAllowed();
} // _readData


/** 
 * analyses Schema from xml Data Source and stores relevant Information into
 * _types, _lens and _nulls arrays.
 */
ajaxForms._prepareTypes = function(schema)
{
  var n, colname, dtype, attrList;
  
  if ((schema != null) && (ajaxForms._types == null)) {
    attrList = schema.selectNodes("./s:ElementType/s:AttributeType");
    ajaxForms._types = new Array();
    ajaxForms._nulls = new Array();
    ajaxForms._lens = new Array();
    
    for (n = 0; n < attrList.length; n++) {
      colname = attrList[n].getAttribute("name");
      dtype = attrList[n].selectSingleNode("./s:datatype");
      ajaxForms._types[colname] = dtype.getAttribute("dt:type");
      ajaxForms._nulls[colname] = ( dtype.getAttribute("rs:maybenull") != "false") ;
      
      if (ajaxForms._types[colname] == "string") {
        ajaxForms._lens[colname] = dtype.getAttribute("dt:maxLength");
      } else if (ajaxForms._types[colname] == "number") {
        ajaxForms._lens[colname] = new Array(2);
        ajaxForms._lens[colname][0] = dtype.getAttribute("rs:precision");
        ajaxForms._lens[colname][1] = dtype.getAttribute("rs:scale");
      }
    } // for
  } // if
} // _prepareTypes


/** 
* Fill rootobj with appropriate value of the xrec reflecting xfmt.
* Include all named sub-elements by recursion.
* @param rootobj root of objects to process
* @param xrec xml of the select
*/
ajaxForms._fillForm = function (xrec, rootobj) {
  var col;
  var n, s, txt;
  var xmlType; // dataType specified by XML Schema
  var fmt;     // dataType used for in/output
  var t, objList, objnr, obj, nam;

  if ((rootobj != null) && (xrec != null)) {
    // fill objects with dataType transformations
    ajaxForms.rowscount = xrec.lastChild.lastChild.childNodes.length;
    objList = ajaxForms._tagIn.concat(ajaxForms._tagOut);
    for (objnr = 0; objnr < objList.length; objnr++) {
      obj = objList[objnr];
      nam = obj.name;
      if ((nam == null) || (nam == "")) continue;

      col = xrec.lastChild.lastChild.firstChild.attributes.getNamedItem(nam);
      xmlType = ((ajaxForms._types == null) ? ((obj.dtType == null) ? "string" : obj.dtType) : ajaxForms._types[nam]);
      fmt = ((obj.dtType != null) ? obj.dtType : xmlType);
      obj._dtdt = xmlType; // used for type checking and getData

      if (col == null) {
        ajaxForms._fillTag(obj, "");
      } else {

        if ((ajaxForms._types == null) || (fmt == null) || (fmt == "") || (fmt == "string")) {
          ajaxForms._fillTag(obj, col.nodeValue);
        } else if ((fmt == "number") && (ajaxForms._lens[nam] != null)) {
          col.dataType = fmt;
          //txt = Format_Number2(parseFloat(col.nodeTypedValue), ajaxForms._lens[nam][1]);
          txt = nls.decimal.toString(parseFloat(col.nodeTypedValue), ajaxForms._lens[nam][1]); // CKE 12.08.2008
          ajaxForms._fillTag(obj, txt);
        } else {
          // try to set the value
          try {
            if ((xmlType == "dateTime") && (col.nodeValue.length > 19)) {
              col.nodeValue = col.nodeValue.substr(0, 19);
            }
            if (xmlType == "dateTime" && col.nodeValue.indexOf("T") > 0) {
              var dateparts = col.nodeValue.split("T")[0].split("-");
              if (typeof _utils_const_.dateformat != 'undefined' && _utils_const_.dateformat != null) {
                col.nodeValue = formatDateCustom(new Date(dateparts[0], dateparts[1] - 1, dateparts[2]), _utils_const_.dateformat);
              }
              else 
              {
                col.nodeValue = dateparts[2] + "." + dateparts[1] + "." + dateparts[0]; // TODO: localization
              }
            }
            if (xmlType != null) {
              col.dataType = xmlType;
            }
            txt = _formatXMLValue(fmt, col.nodeTypedValue);
            ajaxForms._fillTag(obj, txt);
          } catch (e) {
            try {
              ajaxForms._fillTag(obj, col.nodeValue);
            } catch (e) { };
          } // try
        }
      }

      if ((ajaxForms._nulls != null) && (ajaxForms._nulls[nam] == false) && (obj.notNull != "false")) {
        obj.notNull = "1";
        if (obj.className == "") {
          obj.className = "NOTNULL";
        }
      }
    } // for
  }
  ajaxForms._tagIn = new Array(); // in/out elements: INPUT, TEXTAREA, SELECT
  ajaxForms._tagOut = new Array(); // out elements: SPAN, DIV, TD


  // transfer id & timestamp
  n = xrec.lastChild.lastChild.firstChild.attributes.getNamedItem("id");
  if (n == null) {
    n = xrec.lastChild.lastChild.firstChild.attributes.getNamedItem("ID");
  }
  if (n != null) {
    rootobj._id = n;
  }
  n = xrec.lastChild.lastChild.firstChild.attributes.getNamedItem("timestamp");
  if (n == null) {
    n = xrec.lastChild.lastChild.firstChild.attributes.getNamedItem("TIMESTAMP");
  }
  if (n != null) {
    rootobj._ts = n;
  }
  if (rootobj.getAttribute("onFormReady") != null) { // FF
    try {
      eval("window." + rootobj.getAttribute("onFormReady"))(rootobj);
    } catch (e) {
      askException(e.description);
    }
  }
}        // _fillForm


/** 
  * Fill the value/innerHTML of a obj to the typed value of xcol.
  * Attach field events.
  * @param obj HTML Object receiving the value
  * @param txt String the value
  */
ajaxForms._fillTag = function(obj, txt)
{
  var dtdt;
  var tn = obj.tagName;
  txt = txt.replace(/[\s\xA0]+$/, ""); // .replace(/^[\s\xA0]+/, "");

  //TODO
  txt = txt.replace(/%28/g, "(").replace(/%29/g, ")");

  // then: put into value/innerText
  if (tn  == "INPUT") {
    if (obj.type == "checkbox") {
      obj.checked = ((txt == '1') || (txt.toLowerCase() == 'true'));
    } else if (obj.type == "radio") {
      obj.checked = (txt == obj.value);
    } else {
      // align numbers to the right
      dtdt = obj.getAttribute("_dtdt");
      if ((dtdt == "number") || (dtdt == "i2") || (dtdt == "i4") || (dtdt == "int")
        && (obj.style.textAlign != "right"))
        obj.style.textAlign = "right";
      obj.value = txt;
    } // if


  } else if ((tn == "DIV") && (obj.className == "IMSHTMLTEXT")) {
    obj.innerHTML = txt.replace(/<\/?script[^>]*>/ig, "");

  } else if ((tn == "DIV") && (obj.className == "IMSDATAPART")) {
    obj.setValue(txt.replace(/<\/?script[^>]*>/ig, ""));

  } else if ((tn  == "SPAN") || (tn == "DIV") || (tn == "TD")) {
    obj.innerText = txt;

  } else if (tn  == "TEXTAREA") {
    obj.value = txt;

  } else if (tn == "SELECT") {
    var o, cnt = 0;
    
    while ((cnt < obj.options.length) && (obj.options[cnt].value != txt)) {
      cnt++;
    } // while
    
    if (cnt < obj.options.length) {
      obj.selectedIndex = cnt;
    } else {
      o = document.createElement("OPTION");
      o.text = o.value = txt;
      try {
        obj.add(o, null);  // add(o) is only IE, causes a crash in FF - add(o, position) is standard compliant
        obj.selectedIndex = cnt;
      } catch (e) { }
    }
  }
  if (obj.getAttribute("onFormSet") != null) { // FF
    //alert("_fillTag.onFormSet" + obj + ", txt: " + txt);
    try {
      eval("window." + obj.getAttribute("onFormSet"))(obj);
    } catch(e) {}
  }
  
} // _fillTag


if (!window.ActiveXObject) {

  Document.prototype.selectNodes = function(sXPath) {
    var oEvaluator = new XPathEvaluator();
    var oResult = null;
    try {
      oResult = oEvaluator.evaluate(sXPath, this, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
    } catch (ex) {}
    var aNodes = new Array();
    
    if (oResult != null) {
      var oElement = oResult.iterateNext();
      while(oElement) {
        aNodes.push(oElement);
        oElement = oResult.iterateNext();
      }
    }
    return aNodes;
  }

  Document.prototype.selectSingleNode = function(sXPath) {
    var oEvaluator = new XPathEvaluator();
    // FIRST_ORDERED_NODE_TYPE returns the first match to the xpath.
    var oResult = null;
    try {
      oResult = oEvaluator.evaluate(sXPath, this, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
    } catch (ex) {}
    if (oResult != null) {
      return oResult.singleNodeValue;
    } else {
      return null;
    }              
  }

} // if not IE


///<summary>Walk all html INPUT, TEXTAREA and SELECT elements contained by the passed object
///and return the current values.</summary>
///<param name="obj">A reference or an id of the html object containing the ajax form UI.</param>
///<returns>The data of inside the form as XML conform string.</returns>
ajaxForms.getDataStr = function (obj, index) {
  var n, aList, elem, val, dttype;
  var isvalid = true;
  var elemvalid = true;
  var count = 0;
  var xdata = "<data>";
  if (index != null) { // to be used by the hotline manager
    xdata = "<data index=\"" + index + "\">";
  }
  obj = ajaxForms._getFormObj("ajaxForms.getData", obj);

  var lbls = document.getElementsByTagName("LABEL");

  // get text & checked
  aList = obj.getElementsByTagName("INPUT");
  for (n = 0; n < aList.length; n++) {
    elem = aList[n];
    if (elem.validate || elem.attributes["validate"]) {
      elemvalid = validateElem(elem, lbls);
      count += (elemvalid ? 0 : 1);
      isvalid = (isvalid ? elemvalid : isvalid);
    }
    if (isvalid && (elem.name != null) && (elem.name != "") && (elem.name.charAt(0) != "_")) {
      if (elem.getData != null) {
        val = elem.getData();
      } else if (elem.type == "text") {
        val = elem.value;
      } else if (elem.type == "checkbox") {
        val = (elem.checked ? 1 : 0);
      } else if (elem.type == "radio") {
        val = getRadioValue(elem.name);
      } else {
        val = "";
      } // if  
      dttype = ((elem.getAttribute("_dtdt") && elem.getAttribute("_dtdt") != "string") ?
      (dttype = " dttype='" + ((elem.attributes["dtformat"] != null && elem.getAttribute("_dtdt") == "dateTime") ? 
        elem.getAttribute("_dtdt") + '.' + elem.attributes["dtformat"].value : elem.getAttribute("_dtdt")) + "'") 
      : "");
      
      val = ((elem.getAttribute("_dtdt") && elem.getAttribute("_dtdt") == "string") ? ajaxForms.formatForXML(val) : val);
      val = ((elem.getAttribute("_dtdt") && elem.getAttribute("_dtdt") == "number") ? val.replace(/,/g, ".") : val);
      val = ((elem.getAttribute("_dtdt") && elem.getAttribute("_dtdt") == "dateTime" && val.match(/\D+/)) ? getSQLFmtFromLocal(val) : val);
      xdata += "<" + elem.name + dttype + ">" + val + "</" + elem.name + ">";
    } // if
  } // for

  // get text
  aList = obj.getElementsByTagName("TEXTAREA");
  for (n = 0; n < aList.length; n++) {
    elem = aList[n];
    if (elem.validate || elem.attributes["validate"]) {
      elemvalid = validateElem(elem, lbls);
      count += (elemvalid ? 0 : 1);
      isvalid = (isvalid ? elemvalid : isvalid);
    }
    if (isvalid && (elem.name != null) && (elem.name != "") && (elem.name.charAt(0) != "_")) {
      if (elem.getData != null) {
        val = elem.getData();
      } else {
        val = elem.value;
      } // if  

      //TODO
      val = ajaxForms.formatForXML(val);

      xdata += "<" + elem.name + ">" + val + "</" + elem.name + ">";
    } // if
  } // for

  // get value of selected option
  aList = obj.getElementsByTagName("SELECT");
  for (n = 0; n < aList.length; n++) {
    elem = aList[n];
    if (elem.validate || elem.attributes["validate"]) {
      elemvalid = validateElem(elem, lbls);
      count += (elemvalid ? 0 : 1);
      isvalid = (isvalid ? elemvalid : isvalid);
    }
    if (isvalid && (elem.name != null) && (elem.name != "") && (elem.name.charAt(0) != "_")) {
      if (elem.getData != null) {
        val = elem.getData();
      } else {
        val = elem.value;
      } // if  
      dttype = ((elem.getAttribute("_dtdt") && elem.getAttribute("_dtdt") != "string") ? (dttype = " dttype='" + elem.getAttribute("_dtdt") + "'") : "")
      xdata += "<" + elem.name + dttype + ">" + val + "</" + elem.name + ">";
    } // if
  } // for
  if (isvalid) {
    xdata += "</data>";
  } else {
    xdata = "c" + count;
  }

  return (xdata);
}     // ajaxForms.getDataStr


/// <summary>
/// Replace those characters disallowed in XML text nodes.
/// </summary>
/// <param name="data">any string</param>
/// <returns>a xml encoded string</returns>
ajaxForms.formatForXML = function(data) {
  var strdata = data.toString(); // FF
  strdata = strdata.replace(/&/g, "&amp;");
  //strdata = strdata.replace(new RegExp("\"", "g"), "&quot;"); // nur für Attributwerte nötig
  strdata = strdata.replace(new RegExp("'", "g"), "''");
  strdata = strdata.replace(/</g, "&lt;");
  strdata = strdata.replace(/>/g, "&gt;");

  //TODO
  strdata = strdata.replace(/\(/g, "%28");
  strdata = strdata.replace(/\)/g, "%29");
  
  return (strdata);
} // formatForXML




// ---------------- dbfo database form object --------------------

var dbfo = {

  dbcursor: -1, // Position in the result set
  length: 0, // count of selected records
  cobj: null,
  idarray: null, // all ids of the select: idarray[dbcursor] current record set
  colsel: "",
  tab: "",
  selected: "",
  

  /**
    * Reads the dataset on a the selected position of the collection.
    * @pageid: id from the idlist (coluumn PAGEID)
    */
  cursorData: function(tabname, sel, formname)
  {
    formname = formname ? formname : 'imsform';
    // alert("cursorData: formname: " + formname + ", sel: " + sel);
    tabname = (tabname ? tabname : this.tab);
    var schemadata = proxies.DBUse.GetComplete(tabname, sel);
    ajaxForms.readData(schemadata, formname);    
    this.cobj.value = this.dbcursor+1 + " / " + this.length;
    if (typeof setIframeSrc == "function") {
      setIframeSrc();
    }
   if (typeof setPageHeader == "function") {
      setPageHeader();
    }
   if (typeof setJoinInfo == "function") {
      setJoinInfo();
    }

  }, // cursorData

  posData: function()
  {
    var arraypos = document.getElementById("_COUNT").value;
    this.dbcursor = parseInt(arraypos)-2;
    this.nextData();
  }, // posData

  /**
    * Select for a special id.
    */
  searchId: function(tabname, idsel, posid, csel)
  {
    this.clearData();
    idsel += " where " + tabname + "ID=" + posid;
    this.searchData(tabname, idsel, csel, 0);
  },
  
  
  /**
    * Select for the id list of the collection.
    * Toggle between search result and search condition.
    */
  searchData: function(tabname, idsel, csel, pos)
  {
    var cond = "";
    this.cobj = document.getElementById('_COUNT');
    this.tab = tabname;
    // alert("searchData: idsel: " + idsel + ", csel: " + csel + ", _COUNT.value: " + this.cobj.value);
    if (this.cobj.value != "" && this.cobj.value != "0") {
      this.resetSearch();
      //cond = this.selected;
    } else {
      var searchValue = document.getElementById('_SEARCH').value;
      var externsearch = decodeURIComponent(searchValue);
      cond = selectedFields(); //document.getElementById('_SEARCH').value;
      if (externsearch) {
        cond += ("&" + externsearch);
      }
      if (cond) {
        this.selected = cond.replace(/%25/g, "%").replace(/%2B/g, "+");
        idsel += " where " + proxies.DBUse.SearchCond(cond);
      }
      var sort = document.getElementById('_SORT').value;
      if (sort) {
        idsel += " order by " + sort;
      }
      // alert("searchData(): " + idsel);
      var idlist = proxies.DBUse.objGetRowsString(tabname, idsel, ",", ",", "");
      if (idlist) {
        this.idarray = idlist.split(",");
        this.length = this.idarray.length;
        this.cobj.value = this.length;
        this.dbcursor = (pos ? pos : 0);
        this.colsel = csel;
        //this.tab = tabname;
        csel += this.idarray[this.dbcursor];
        this.cursorData(tabname, csel);
      } else {
        if (this.selected && (this.cobj.value == "" || this.cobj.value == "0")) {
          selvals = this.selected.split("&");
          for (var i = 0; i < selvals.length; i++) {
            selvals[i] = selvals[i].replace("=", "==");
            var inp = document.getElementById(selvals[i].split("==")[0]);
            if (inp) {
              inp.value = selvals[i].split("==")[1];
            } else {
              inp = document.getElementById("_SEARCH");
              inp.value = "";
            }
          }
        }
        this.cobj.value = "0";
      }
    }
  }, // searchData



  /**
    * check Buttons to be used.
    */
  checkAllowed: function()
  {
    if (typeof checkAllowed == "function") {
      checkAllowed();
    } else {
      var obj = document.getElementById("ctl00_ContentPlaceHolder1_Menue");
      if(obj) {
        var allfctions = document.getElementById("ctl00_ContentPlaceHolder1_Menue").getElementsByTagName("IMG");
        for (var i = 1; i < allfctions.length; i++) { 
           allfctions[i].style.display = "inline";
        } // for
        allfctions = document.getElementById("ctl00_ContentPlaceHolder1_Menue").getElementsByTagName("LABEL");
        for (var i = 1; i < allfctions.length; i++) {
          allfctions[i].style.display = "inline";
        } // for
      }
    }
//    if (typeof checkAllowedExt == "function") { // FF: onLoadPage
//      checkAllowedExt();
//    }

  },
  

  /**
    * Replace the search parameters to the form.
    */
  resetSearch: function()
  {
    var selvals;
    
    // alert("resetSearch: this.selected: " + this.selected);
    this.clearData();
    if (this.selected) {
      selvals = this.selected.split("&");
      for (var i = 0; i < selvals.length; i++) {
        var inp = document.getElementById(selvals[i].split("=")[0]);
        if (inp) {
          inp.value = selvals[i].split("=")[1];
        } else {
          inp = document.getElementById("_SEARCH");
          inp.value = (inp.value ? inp.value + "&" + selvals[i] : selvals[i]);
        }
      }
    }
    this.selected = "";
    
  }, // resetSearch


  /**
    * Read the first dataset of the collection.
    */
  firstData: function()
  {
    try {
      this.dbcursor = 0;
      // alert("firstData: colsel: " + this.colsel);
      this.cursorData(this.tn, this.colsel + this.idarray[0]);
    } catch (ex) {
    }
  }, // firstData


  /**
    * Read the next dataset of the collection.
    */
  nextData: function()
  {
    try {
      // alert("nextData: dbcursor: " + this.dbcursor + ", length: " + this.length);
      this.dbcursor = (this.dbcursor < this.length-1 ? this.dbcursor + 1 : this.length-1);
      this.cursorData(this.tn, this.colsel + this.idarray[this.dbcursor]);
    } catch (ex) {
      this.dbcursor -= 1
    }
  }, // nextData


  /**
    * Read the previous dataset of the collection.
    */
  prevData: function()
  {
    try {
      // alert("prevData: dbcursor: " + this.dbcursor + ", length: " + this.length);
      this.dbcursor = (this.dbcursor == 0 ? 0 : this.dbcursor - 1);
      this.cursorData(this.tn, this.colsel + this.idarray[this.dbcursor]);
    } catch (ex) {
      this.dbcursor += 1;
    }
  }, // prevData


  /**
    * Read the last dataset of the collection.
    */
  lastData: function()
  {
    try {
      this.dbcursor = this.length-1;
      // alert("lastData: dbcursor: " + this.dbcursor + ", idarray[dbcursor]: " + this.idarray[this.dbcursor]);
      this.cursorData(this.tn, this.colsel + this.idarray[this.dbcursor]);
    } catch (ex) {
    }
  }, // lastData


  /**
    * Write the current dataset to the database.
    * @param formname Id of the form element
    */
  insertData: function(formname)
  {
    var inp = document.getElementById('IUSER');
    if (inp) {
      inp.value = "[IMSUSER]";
    }
    inp = document.getElementById('IDATE');
    if (inp) {
      inp.value = new Date().getXmlDateTime();
    }
    inp = document.getElementById('UUSER');
    if (inp) {
      inp.value = "";
    }
    inp = document.getElementById('UDATE');
    if (inp) {
      inp.value = "";
    }
    inp = document.getElementById('_DEFVAL');
    if (inp && inp.value) {
      this.setDefVals(inp.value);
    }
    
    formname = (formname ? formname : 'imsform');
    //alert("insert" + formname);
    var formdata = ajaxForms.getDataStr(document.getElementById(formname));
    
    if (formdata.indexOf("data") == 1) {
      // alert(formdata);
      proxies.DBUse.InsertData.func = dbfo.insertDataExt;

      proxies.DBUse.InsertData(this.tab, formdata);
      //alert("insertData: count: " + count + ", formdata: " + formdata);
      //if (count > 0) {
      //}
      try {
        FMBox.open("ct100_myFMB", "", "");
      } catch (ex) {
        alert("The data was refreshed.");
      }
    } else {
      FMBox.open("ct100_myFMB", formdata.replace(/c/, "") + " wrong input", "Error");
    }

  }, // insertData
  

  /**
    * processing after the data was inserted.
    * Can be overwritten bythe local code of the page.
    * @count: rows affected
    */
  insertDataExt: function(count)
  {
    if (!dbfo.cobj) {
      dbfo.cobj = document.getElementById('_COUNT');
    }
    
    if (dbfo.cobj.value == "0" || dbfo.cobj.value == "") {
      //alert("Daten wurden eingefügt.");
      dbfo.cobj.value = "1";
      dbfo.selected = selectedFields().replace(/%25/g, "%").replace(/%2B/g, "+");
      dbfo.searchData(dbfo.tab, idsel, dbfo.colsel, dbfo.length);
      searchData();

      if (document.location.pathname.indexOf("/page.aspx") > 0 && document.getElementById("CONTENTID").value == "0") {
        document.getElementById("CONTENTID").value = document.getElementById("_PAGEID").value;
        dbfo.updateData();
      } else if (document.location.pathname.indexOf("/contentpage.aspx") > 0) {
        document.getElementById("CONTENTID").value = document.getElementById("_RESOURCEID").value;
        dbfo.updateData();
      }
      //document.getElementById("_SEARCH").value = "";
    } else {
      dbfo.resetSearch();
      dbfo.searchData(dbfo.tab, idsel, dbfo.colsel, dbfo.length);
    }
    if (count > 0) {
      if (typeof insertDataExt == "function") {
        insertDataExt(count);
      }
      try {
        if(dbfo.idarray) {
          var allfctions = document.getElementById("ctl00_ContentPlaceHolder1_Menue").getElementsByTagName("IMG");
          for (var i = 1; i < allfctions.length; i++) {
            allfctions[i].style.display = "inline";
          } // for
          allfctions = document.getElementById("ctl00_ContentPlaceHolder1_Menue").getElementsByTagName("LABEL");
          for (var i = 1; i < allfctions.length; i++) {
            allfctions[i].style.display = "inline";
          } // for
        }
      } catch(e) {
      }

    } else {
      alert("Daten konnten nicht eingefügt werden"); // nolng
    }
  },

  
  /**
    * Write default values into the empty fields of the current dataset.
    * @param defvals: default values as option string.
    *                 COLNAME:Column Value;COLNAME2:Column Value 2;...
    */
  setDefVals: function(defvals)
  {
    var alldefvals = defvals.split(";");
    for (var i = 0; i < alldefvals.length; i++) {
      var colandval = alldefvals[i].split(":");
      var valinp = document.getElementById(colandval[0]);
      valinp.value = (valinp.value ? valinp.value : colandval[1]);
    }
  },


  /**
    * Update the current dataset from the database.
    * @param formname Id of the form element
    * @param cond where cond for the sql select
    */
  updateData: function(formname, cond)
  {
    var nr = -1;
    var inp = document.getElementById('UUSER');
    if (inp) {
      inp.value = "[IMSUSER]";
    }
    inp = document.getElementById('UDATE');
    if (inp) {
      inp.value = new Date().getXmlDateTime();
    }
    formname = (formname ? formname : 'imsform');
    cond = (cond ? cond : (this.tab + "ID"));

    var formdata = ajaxForms.getDataStr(document.getElementById(formname));
        if (formdata.indexOf("data") > 0) {

    if (this.dbcursor >= 0) {
      nr = proxies.DBUse.UpdateData((cond + "=" + this.idarray[this.dbcursor]), this.tab, formdata);
      // alert("updateData: cond: " + cond + "=" + this.idarray[this.dbcursor] + ", nr: " + nr);
      //alert("updateData: nr: " + nr);
      if(nr > 0) {
        this.cursorData(this.tn, this.colsel + this.idarray[this.dbcursor]);
        //                        msg,                 beep, awayFromRight, awayFromBottom,color
        //                                                   bottomleftcorner: 1020, -30
        //                                                   bottomrightcorner: -30, -30
        //                                                   topleftcorner: 1020, 900
        //                                                   toprightcorner: -30, 900
        //                                               ca. centerscreen: 460, 435
        //                                            fairly bottomrightcorner: -11, -3
        //Systemcolors: curr.implemented:
        //LightBlue,LightGray,DarkOrange,LightCyan,LawnGreen,LightYellow,LimeGreen,LightSkyBlue,YellowGreen
        //MediumOrchid,MediumSeaGreen,PapayaWhip,PeachPuff,PowderBlue,SeaShell,SlateBlue,Tomato,Yellow,LemonChiffon
        //BOSCH-RGB-Colors: implemented: 1)[223,233,244], 2)[180,198,217]
        //proxies.DBUse.showAndFade("Die Daten wurden aktualisiert.", false, -11, -3, "223,233,244", true);
        try {
          FMBox.open("ct100_myFMB", "", "");
        } catch (ex) {
          alert("Die Daten wurden aktualisiert."); // nolng
        }
      } else if (nr == 0) {
        alert ("Die Daten haben sich geändert. Bitte aktualisieren Sie die Seite.");
      } else if (nr == -1) {
        alert ("Die geänderten Daten sind fehlerhaft (Doppelte Schlüsselwerte?)."); // nolng
      }
    }
        } else {
          alert("Your data is incomplete or incorrect!");
        }
    return nr;
  }, // updateData


  /**
    * Update the current dataset from the database.
    * @param formname Id of the form element
    * @param cond where cond for the sql select
    */
  updateDataDirect: function(formname, cond)
  {
    var nr = -1;
    var inp = document.getElementById('UUSER');
    if (inp) {
      inp.value = "[IMSUSER]";
    }
    inp = document.getElementById('UDATE');
    if (inp) {
      inp.value = new Date().getXmlDateTime();
    }
    formname = (formname ? formname : 'imsform');
    cond = (cond ? cond : (this.tab + "ID"));

    var formdata = ajaxForms.getDataStr(document.getElementById(formname));
    if (this.dbcursor >= 0) {
      nr = proxies.DBUse.UpdateData((cond + "=" + this.idarray[this.dbcursor]), this.tab, formdata);
      if(nr > 0) {
        this.cursorData(this.tn, this.colsel + this.idarray[this.dbcursor]);
      } else if (nr == 0) {
        alert ("Die Daten haben sich geändert. Bitte aktualisieren Sie die Seite.");
      } else if (nr == -1) {
        alert ("Die geänderten Daten sind fehlerhaft (Doppelte Schlüsselwerte?)."); // nolng
      }
    }
  }, // updateDataDirect


  /**
    * Delete the current dataset from the database.
    * @param cond where cond for the sql select
    */
  deleteData: function(cond)
  {
    var nr = -1;
    var rsid = this.idarray[this.dbcursor];
    var ok = confirm("Wollen Sie diesen Datensatz wirklich löschen?"); // nolng
    
    if (ok == true) {
      cond = (cond ? cond : (this.tab + "ID"));
      nr = proxies.DBUse.DeleteData((cond + "=" + rsid), this.tab);
      // alert("deleteData: cond: " + cond + "=" + rsid + ", nr: " + nr);
      if (nr > 0) {
        // shift
        var allids = "," + this.idarray.join(",") + ",";
        allids = allids.replace("," + rsid + ",", ",").replace(/^\,|\,$/g, "");
        this.idarray = allids.split(",");
        this.length -= 1;
        this.dbcursor = (this.dbcursor < this.length-1 ? this.dbcursor : this.length-1);
        
        this.cursorData(this.tn, this.colsel + this.idarray[this.dbcursor]);
      } else {
        alert ("Der Datensatz kann nicht gelöscht werden. Existierende Zuordnungen müssen zuerst gelöscht werden."); // nolng
      }
    }
  }, // deleteData
  
  
  /**
    * Delete the current dataset from the database WITHOUT user-confirm.
    * @param cond where cond for the sql select
    */
  deleteDataDirect: function(cond)
  {
    var nr = -1;
    var rsid = this.idarray[this.dbcursor];
    cond = (cond ? cond : (this.tab + "ID"));
    nr = proxies.DBUse.DeleteData((cond + "=" + rsid), this.tab);
    // alert("deleteData: cond: " + cond + "=" + rsid + ", nr: " + nr);
    if (nr > 0) {
      // shift
      var allids = "," + this.idarray.join(",") + ",";
      allids = allids.replace("," + rsid + ",", ",").replace(/^\,|\,$/g, "");
      this.idarray = allids.split(",");
      this.length -= 1;
      this.dbcursor = (this.dbcursor < this.length-1 ? this.dbcursor : this.length-1);
      
      this.cursorData(this.tn, this.colsel + this.idarray[this.dbcursor]);
    } else {
      alert ("Der Datensatz kann nicht gelöscht werden. Existierende Zuordnungen müssen zuerst gelöscht werden."); // nolng
    }
  }, // deleteDataDirect
  
  
  /**
    * Delete the current dataset from the database.
    * @param cond where cond for the sql select
    */
  clearData: function(formname)
  {
    // alert("clearData: selected: " + this.selected + ", _SEARCH.value" + document.getElementById("_SEARCH").value + ", dbcursor: " + this.dbcursor);
    formname = (formname ? formname : 'imsform');
    ajaxForms.clearData(formname);
    if (this.cobj) {
      this.cobj.value = "";
    }
    this.dbcursor = -1;
  } // clearData

} // END dbfo database form object


// ------------ search utilities ------------------

/**
  * set the url search parameters into the input _SEARCH.
  * if there is _search=0 in the url no search will be done.
  * additionl params are served
  */
function useUrlSearch()
{
  if (window.location.search.toLowerCase().indexOf("_search=0") > 0) {
    presetData();
  } else if (window.location.search.length > 1) {
    document.getElementById("_SEARCH").value = window.location.search.replace("?", "");
    searchData();
  }
} // useUrlSearch


/**
  * presets data on current loadet page without searchData().
  * there might be additional params which won't fit.
  */
function presetData()
{
  if(document.getElementById("_SEARCH")) {
    document.getElementById("_SEARCH").value = "";
  }
  
  // "_search=0" never should be first URL-param
  // for example see um/ugrouplist.aspx
  var tmp = window.location.search.replace(/\&_search=0/ig, "").replace(/\?/g, "");
  
  if(tmp.length > 0) {
    // use this params instett of Request
    var i;
    var paramArr = tmp.split("&");
    for(i = 0;i < paramArr.length;i++) {
      tmp = paramArr[i];
      var tmpName = tmp.split("=")[0];
      var tmpVal = tmp.split("=")[1];
      if(document.getElementById(tmpName)) {
        document.getElementById(tmpName).value = tmpVal;
      } // if
    } // for
  } // if
} // presetData


/**
  * Get the search values from the form
  * @return URL-Parameter "inputname1=inputval1&inputname2=in..."
  */
function selectedFields()
{
  //var inputlist = null; // alle Input der xxxSel.asp-Seite
  var index = "";       // ausgewaehlte Gruppierung
    
  var i;                // Zaehler
  var selection = "";   // return: "&inputname1=inputeintrag&inputname2=in..."
  var inputlist = document.getElementsByTagName("INPUT");
  var likestrobj = document.getElementById("searchrepl");
  var searchrepl = (likestrobj ? likestrobj.value : "");
  
  for (i = 0; i < inputlist.length; i++) 
  {  
    if (inputlist[i].name && (inputlist[i].name.charAt(0) != "_")) {
      if ((inputlist[i].type == "checkbox") && (inputlist[i].checked) && !inputlist[i].disabled) { 
       selection += "&" + inputlist[i].name + "=1";
      } else if ((inputlist[i].type == "text") && (inputlist[i].value)) {
        if (searchrepl) {
          selection += "&" + inputlist[i].name + "=" + searchrepl.replace("xxx7xxx", inputlist[i].value).replace(/%%/g, "%");
        } else {
          selection += "&" + inputlist[i].name + "=" + inputlist[i].value;
        }
      }
    }
  } // for

  inputlist = document.getElementsByTagName("SELECT");
  for (i = 0; i < inputlist.length; i++) {
    //alert("selectedFields");
    if (inputlist[i].id && inputlist[i].getAttribute("sort") != "none") {
      var selval = inputlist[i].value;
      try {
        var sorted = $.makeArray($("#" + inputlist[i].id + " option")).sort(function (a, b) { return $(a).text() > $(b).text() ? 1 : -1; });
        $("#" + inputlist[i].id).empty().append(sorted);
        inputlist[i].value = selval;
      } catch (e) { /* no sorting */ }
    }
    if ((inputlist[i].value) && (inputlist[i].name) && (inputlist[i].name.charAt(0) != "_") && (!inputlist[i].disabled)) { 
      selection += "&" + inputlist[i].name + "=" + inputlist[i].value;
    } // if
  } // for
  
  inputlist = document.getElementsByTagName("TEXTAREA");
  for (i = 0; i < inputlist.length; i++) {
    if ((inputlist[i].value) && (inputlist[i].name) && (inputlist[i].name.charAt(0) != "_") && (!inputlist[i].disabled)) { 
      selection += "&" + inputlist[i].name + "=" + inputlist[i].value;
    } // if
  } // for
  if (selection) {
    selection = selection.substr(1).replace(/\*/g, "%").replace(/%/g, "%25").replace(/\+/g, "%2B");
  }
  
  return selection;
} // selectedFields 


// ------------ common functions -----------------

/** Generierung von OPTION Elementen zu einem SELECT Element
* auf Basis einer textuellen Liste.
* Die Liste besteht aus Elementen, die mit Kommas getrennt sind.
* Jedes Element besteht aus einem value-Text Paar, das mit Doppelpunkten getrennt ist.
* Beispiel: "de:Deutsch,en:englisch,fr:französisch".
* Bei fehlenden Labels wird die Nummer des Elementes (ab 1 gezählt) als value verwendet.
* Values, die mit einer Klammer starten werden nicht uebernommen aber mitgezählt.
* @param selObj SELECT Element
* @param optstr Liste der zu generierenden Optionen.
* @param selval der default anzuzeigende Wert.
*/
function createOptions(selobj, optstr, selval)
{

  var n; // Zaehler
  var o; // OPTION Element
  var s; // temp String

  selobj.length = 0;

  optstr = optstr.split(",");
  for (n = 0; n < optstr.length; n++) {
    s = optstr[n];
    if (s.charAt(0) != '(' && s != '') {
      o = document.createElement("OPTION");
      if (s.indexOf(':') < 0) {
        o.value = n+1;
        o.innerHTML = s;
      } else {
        s = s.split(':');
        o.value = s[0].split('[')[0];
        o.innerHTML = s[1]; // nolng
      } // if
      selobj.appendChild(o);
      if ((selval != null) && ((o.value == selval) || (o.innerText == selval))) {
        o.selected = true;
      }
    }
  } // for
} // createOptions

/**
  * clear all objects with search values
  * @param obj: HTMLobject with search fields
  */
function clearSearch(obj)
{
  // clear the text of fields and uncheck checkboxes.
  var inps = obj.getElementsByTagName("INPUT");
  for (n = 0; n < inps.length; n++) {
    if ((inps[n].name != null) && (inps[n].name != "")) {
      if (inps[n].type == "text") {
        inps[n].value = "";
      } else if (inps[n].type == "checkbox") {
        inps[n].checked = false;
      } // if
    } // if
  } // for

  // clear the text of textareas
  inps = obj.getElementsByTagName("TEXTAREA");
  for (n = 0; n < inps.length; n++) {
    if ((inps[n].name != null) && (inps[n].name != "")) {
      inps[n].value = "";
    } // if
  } // for

  // because there is no real clear with select objects, the select is reset to the default-value
  inps = obj.getElementsByTagName("SELECT");
  for (n = 0; n < inps.length; n++) {
    if ((inps[n].name != null) && (inps[n].name != "")) {
      inps[n].value = "";
      
      for (o = 0; o < inps[n].options.length; o++) {
        if (inps[n].options[o].defaultSelected) {
          inps[n].selectedIndex = o;
          break;
        }
      } // for
    }
  } // for
} // clearSearch


/**
  * validate an input, select or textarea.
  * @param elem: element to validate
  * validate-checks: 
      len:8 minimum 8 chars
      fct:functionname eval function on page
      @.+\.de|g regex expression with condition
        inverse validation supported through '!' in the condition part
      =column compare to another id
  * @param lbls: list of all labels
  * @return true if the value of the element is valid
  */ 
function validateElem(elem, lbls) 
{
  var valid = false;
  var validation = elem.validate ? elem.validate : elem.attributes["validate"].value; // FF
  var cond = "ig";
  var  val = "";
    
  if (elem.getData != null) {
    val = elem.getData();
  } else if (elem.type == "checkbox") {
    val = (elem.checked ? 1 : 0);
  } else if (elem.type == "radio") {
    val = getRadioValue(elem.name);
  } else {
    val = elem.value;
  }

  if (validation == "*") {
    valid = (val.length > 0);
  } else if (validation.indexOf("fct:") == 0) {
    valid = (eval("window." + validation.replace(/fct:/, ""))(elem));
  } else if (validation.indexOf("len:") == 0) {
    valid = (val.length >= validation.replace(/len:/, ""));
  } else if (validation.indexOf("=") == 0) {
    valid = (val == document.getElementById(validation.replace(/=/, "")).value);
  } else {
    if (validation.indexOf("|") > 0) {
      cond = validation.split("|")[1];
    }

    var rex = new RegExp(validation.split("|")[0], cond.replace("!", ""));
    valid = rex.test(val);
    if (validation.indexOf("!") > 0 && validation.indexOf("!") == validation.length - 1) {
      valid = !valid;
    }
  }

  if (lbls != null) {
    for (i = 0; i < lbls.length; i++) {
      if (lbls[i] && lbls[i].htmlFor == elem.name) {
        lbls[i].className = lbls[i].className.replace(" UNVALID", "");
        lbls[i].className = (valid ? lbls[i].className : lbls[i].className + " UNVALID");
      }
    }
  }
  return (valid);
} // validateElem

function getRadioValue(name) {
  var elems = document.getElementsByName(name);
  var val = "";
  for (var i = 0; i < elems.length; i++) {
    if (elems[i].checked) {
      val = elems[i].value;
      break;
    }
  }
  return val;
}

// ------------ common prototypes -----------------


/**
  * Get the SQL-date-string zfor a javascript date object
  * @param date date object
  * @return SQL-date-string (yyyyMMdd)
  */
Date.prototype.toSqlDate = function()
{
  var day, month, year;

  day = String(this.getDate());
  day = (day.length == 1 ? "0" + day : day);
  month = String(this.getMonth() + 1);
  month = (month.length == 1 ? "0" + month : month);
  year = this.getFullYear();
  
  return(year + month + day);
} // toSqlDate


/**
  * Liefert einen XML-Datum-Zeit-String zu einem DateTime-Objekt
  * @param datum DateTime-Objekt
  * @return XML-Datum-Zeit-String (yyyy-MM-ddT00:00:00)
  */
Date.prototype.getXmlDateTime = function()
{
  var day, month, year, hours, minutes, seconds;

  day = String(this.getDate());
  day = (day.length == 1 ? "0" + day : day);
  month = String(this.getMonth() + 1);
  month = (month.length == 1 ? "0" + month : month);
  year = this.getFullYear();
  hours = String(this.getHours());
  hours = (hours.length == 1 ? "0" + hours : hours);
  minutes = String(this.getMinutes());
  minutes = (minutes.length == 1 ? "0" + minutes : minutes);
  seconds = String(this.getSeconds());
  seconds = (seconds.length == 1 ? "0" + seconds : seconds);

  return(year + "-" + month + "-" + day + "T" + hours + ":" + minutes + ":" + seconds);
} // getXmlDateTime


  /** Format local date to sql date
    * @param datestr Eingabedatum
    * @return local-unspezifisches SQLFormat
    */
  function getSQLFmtFromLocal(datestr)
  {
     if (datestr.indexOf("T") == 10) {
       return (datestr);
     }

    var datestr = datestr.toLowerCase();
    var result = datestr;
    
    return (result);
/*    
    var today = new Date();
    var fmt;

    // separators
    datestr = datestr.replace(/[\.,;:\-\/]/g, " ");
    datestr = datestr.replace(/  /g, " ");  // join spaces into 1 space

    if (datestr.length == 0 || !document.getElementById("LOCALEDATE")) {
      // no datestr
    } else {
      datestr = datestr.split(' ');
      var s = document.getElementById("LOCALEDATE").value;
      result = new Object();
      result.Day = today.getDate();
      result.Month = today.getMonth();
      result.Year = today.getYear();
      s = s.replace(new RegExp(result.Year, "g"), "Y")
      s = s.replace(new RegExp(result.Month+1, "g"), "M")
      s = s.replace(new RegExp(result.Day, "g"), "D");
      var fmt = new Array();
      var dateParts = "DMYy";
      var n = 0;

      for (var i = 0; i < s.length; i++) {
        if (dateParts.indexOf(s.charAt(i)) >= 0) {
          fmt[n++] = s.charAt(i);
        }
      } // for

      var n, f = 0;
      for (n = 0; (n < fmt.length) && (n < datestr.length); n++) {
        if ((datestr[n] == "") || (datestr[n] == null)) {
          // nothing 
        } else if (fmt[f] == "D") {
          result.Day = datestr[n];
          f++;
        } else if (fmt[f] == "M") {
          result.Month = datestr[n] - 1;
          f++;
        } else if ((fmt[f] == "Y") || (fmt[f] == "y")) {
          result.Year = datestr[n];
          f++;
        }
      } // for
      
      // Test for date ranges
      if ((result.Day <= 12) && (result.Month > 11)) {
        // swap day and month ?
        var hilfe = result.Month;
        result.Month = result.Day-1;
        result.Day=hilfe + 1;
      }

      // test for date range
      if ((result.Day <= 0) || (result.Month < 0)
      || (result.Day > 31) || (result.Month > 11)) {
        throw ("bitte ein Datum eingeben."); 
      }
      result = new Date(result.Year, result.Month, result.Day);
      result = result.getXmlDateTime();
    }

    return(result);
*/
  } // getSQLFmtFromLocal


  /** 
    * get format of date
    * @return format-String for date
    */
  function getDateFmt()
  {
    var d = new Date();
    var s = document.getElementById("LOCALEDATE").value;

    s = s.replace(new RegExp(d.getYear(), "g"), "Y")
    s = s.replace(new RegExp(d.getMonth()+1, "g"), "M")
    s = s.replace(new RegExp(d.getDate(), "g"), "D");
    var fmt = new Array();
    var dateParts = "DMYy";
    var n = 0;

    for (var i = 0; i < s.length; i++) {
      if (dateParts.indexOf(s.charAt(i)) >= 0) {
        fmt[n++] = s.charAt(i);
      }
    } // for
    alert('getDateFmt->' + fmt);
    return(fmt);
  } // _getDateFmt

  /**
  * format date object to custom format
  * @param date: javascript date object
  * @param reqformat: requested format i.e. dd.mm.yyyy or yy-mm-dd or ...
  * @return format-String for date
  */
  function formatDateCustom(date, reqformat) {
    var res = '';
    if ($.datepicker != null) {
      var jqformat = reqformat.toLowerCase();
      jqformat = jqformat.indexOf('yyyy') >= 0 ? jqformat.replace('yyyy', 'yy') : jqformat.replace('yy', 'y'); // jquery: one 'y' counts as two
      res = $.datepicker.formatDate(jqformat, date);
    }
    else {
      return date.getDate() + "." + (date.getMonth() + 1) + "." + date.getFullYear();
    }
    return res;
  }
