        /****** BEGIN LICENSE BLOCK *****
         * Copyright (c) 2005-2006 Harmen Christophe and contributors. All rights reserved.
         * 
         * This script is free software; you can redistribute it and/or
         *   modify under the terms of the Creative Commons - Attribution-ShareAlike 2.0
         * <http://creativecommons.org/licenses/by-sa/2.0/>
         * You are free:
         *     * to copy, distribute, display, and perform the work
         *     * to make derivative works
         *     * to make commercial use of the work
         * 
         * Under the following conditions:
         * _Attribution_. You must attribute the work in the manner specified by the
         *   author or licensor.
         * _Share Alike_. If you alter, transform, or build upon this work, you may
         *   distribute the resulting work only under a license identical to this one.
         *     * For any reuse or distribution, you must make clear to others 
         *      the license terms of this work.
         *     * Any of these conditions can be waived if you get permission from 
         *      the copyright holder.
         * 
         * Your fair use and other rights are in no way affected by the above.
         * 
         * This is a human-readable summary of the Legal Code (the full license). 
         * <http://creativecommons.org/licenses/by-sa/2.0/legalcode>
         ***** END LICENSE BLOCK ******/
        function formControlListener(nForm) {
          var bIsValide = true;
          var aFormCtrlSchemes = [["isNotEmpty","Le champ \"%s\" doit être renseigné."],
            ["isInt","Le champ \"%s\" ne correspond pas à un entier valide."]];
          var cLabels = nForm.getElementsByTagName("label");
          var nField;
          for (var i=0; bIsValide && i<cLabels.length; i++) {
            if ((cLabels[i].htmlFor=="") ||
              !(nField=document.getElementById(cLabels[i].htmlFor))) continue;
            for (var j=0; bIsValide && aFormCtrlSchemes[j]; j++) {
              if (hasClassName(cLabels[i],aFormCtrlSchemes[j][0])) {
                if (!eval(aFormCtrlSchemes[j][0]+"(nField.value)")) {
                  bIsValide = false;
                  var textContent = getTextContent(cLabels[i]).replace(/\s{2,}/g," ");
                  textContent = textContent.replace(/^[\s:*]+|[\s:*]+$/g,"");
                  alert(aFormCtrlSchemes[j][1].replace("%s",textContent));
                }
              }
            }
          }
          if (!bIsValide) {nField.focus();}
          return bIsValide;
        }
        function isNotEmpty(s) {return s.replace(/^\s+|\s+$/g,"")!="";}
        function isInt(s) {return isNotEmpty(s)?parseInt(s, 10)==s:true;}
        function hasClassName(oNode,className) {
            return ((" "+oNode.className+" ").indexOf(" "+className+" ")!=-1);
        }
        function getTextContent(oNode) {
          if (typeof(oNode.textContent)!="undefined") {return oNode.textContent;}
          switch (oNode.nodeType) {
            case 3: // TEXT_NODE
            case 4: // CDATA_SECTION_NODE
              return oNode.nodeValue;
              break;
            case 8: // COMMENT_NODE
            case 7: // PROCESSING_INSTRUCTION_NODE
              if (getTextContent.caller!=getTextContent) {
                return oNode.nodeValue;
              }
              break;
            case 9: // DOCUMENT_NODE
            case 10: // DOCUMENT_TYPE_NODE
            case 12: // NOTATION_NODE
              return null;
              break;
          }
          var _textContent = "";
          oNode = oNode.firstChild;
          while (oNode) {
            _textContent += getTextContent(oNode);
            oNode = oNode.nextSibling;
          }
          return _textContent;
        }

