Validación de Datos ( sin jQuery )

Utilidad: Este componente se encarga de validar, formatear, inicializar y restringir los datos de su "contenedor" con JavasCript ( sin jQuery ). Trabaja perfectamente con el elemento <form>, pero no necesariamente tiene que ser con este tipo de elemento. Por eso colocamos la palabra "contenedor", porque puede ser con elementos tales como: <div>, <table>, <section>, etc.


El siguiente código es el archivo index.html

Contiene las posibles variedades de elementos para captura de datos (<input> - incluyendo tipos "radio" y "checkbox" -, <select> y <textarea>), con distintos atributos específicos para mostrar cada uno de los ejemplos correspondientes.

Observe que haremos referencia a 9 archivos.

También note que validaremos el elemento contenedor <section> con el id="contenido"

index.html

 <!DOCTYPE html>
 <html>
 <head>
     <title>JavaScript & JSON</title>
     <meta http-equiv=Content-Type content="text/html; charset=UTF-8">
     <script src="dom.js"></script>
     <script src="inicio.js"></script>
     <script src="array.js"></script>
     <script src="validateData.js"></script>
     <script src="numero.js"></script>
     <script src="date.js"></script>
     <script src="time.js"></script>
     <script src="combo.js"></script>
     <link rel="stylesheet" type="text/css" href="validateData.css">
 </head>
 <body onload="inicio();">
 <h1>Ej.: Formatear, Inicializar, Restringir y Validar Datos (sin jQuery)</h1>
 <section id="contenido">
     <div align="center">
         <div align="center">
             <table class="tabla_grid" style="width: 80%" border="0">
                 <tr>
                     <td>Num (int):</td>
                     <td>
                         <input id="id_num_int"
                                name="num_int"
                                autocomplete="off"
                                size="43"
                                value=""
                                maxlength="100"
                                data-format="integer"
                                data-validation="integer"/>
                     </td>
                 </tr>
                 <tr style="background-color:#f0f0f0">
                     <td>Num (int) >= 1:</td>
                     <td>
                         <input id="id_num_int_min"
                                name="num_int_min"
                                autocomplete="off"
                                size="43"
                                value=""
                                maxlength="100"
                                data-format="integer"
                                data-validation="integer"
                                data-validation-min="1"/>
                     </td>
                 </tr>
                 <tr>
                     <td>Num (int) <= 5000000:</td>
                     <td>
                         <input id="id_num_int_max"
                                name="num_int_max"
                                autocomplete="off"
                                size="43"
                                value=""
                                maxlength="100"
                                data-format="integer"
                                data-validation="integer"
                                data-validation-max="5000000"/>
                     </td>
                 </tr>
                 <tr style="background-color:#f0f0f0">
                     <td>Num (int) >= 1 y <= 5000000:</td>
                     <td>
                         <input id="id_num_int_min_max"
                                name="num_int_min_max"
                                autocomplete="off"
                                size="43"
                                value=""
                                maxlength="100"
                                data-format="integer"
                                data-validation="integer"
                                data-validation-min-max="1-5000000"/>
                     </td>
                 </tr>
                 <tr>
                     <td>Num (float):</td>
                     <td>
                         <input id="id_num_float"
                                name="num_float"
                                autocomplete="off"
                                size="43"
                                value=""
                                maxlength="100"
                                data-format="float"
                                data-validation="float"/>
                     </td>
                 </tr>
                 <tr style="background-color:#f0f0f0">
                     <td>Num (float) >= 0.01:</td>
                     <td>
                         <input id="id_num_float_min"
                                name="num_float_min"
                                autocomplete="off"
                                size="43"
                                value=""
                                maxlength="100"
                                data-format="float"
                                data-validation="float"
                                data-validation-min="0.01"/>
                     </td>
                 </tr>
                 <tr>
                     <td>Num (float) <= 5000000:</td>
                     <td>
                         <input id="id_num_float_max"
                                name="num_float_max"
                                autocomplete="off"
                                size="43"
                                value=""
                                maxlength="100"
                                data-format="float"
                                data-validation="float"
                                data-validation-max="5000000"/>
                     </td>
                 </tr>
                 <tr style="background-color:#f0f0f0">
                     <td>Num (float) >= 0.01 y <= 5000000:</td>
                     <td>
                         <input id="id_num_float_min_max"
                                name="num_float_min_max"
                                autocomplete="off"
                                size="43"
                                value=""
                                maxlength="100"
                                data-format="float"
                                data-validation="float"
                                data-validation-min-max="0.01-5000000"/>
                     </td>
                 </tr>
                 <tr>
                     <td>Num (float 3 dec):</td>
                     <td>
                         <input id="id_num_float_3d"
                                name="num_float_3d"
                                autocomplete="off"
                                size="43"
                                value=""
                                maxlength="100"
                                data-format="float_3d"
                                data-validation="float_3d"/>
                     </td>
                 </tr>
                 <tr style="background-color:#f0f0f0">
                     <td>Num (float 3 dec) >= 0.001:</td>
                     <td>
                         <input id="id_num_float_3d_min"
                                name="num_float_3d_min"
                                autocomplete="off"
                                size="43"
                                value=""
                                maxlength="100"
                                data-format="float_3d"
                                data-validation="float_3d"
                                data-validation-min="0.001"/>
                     </td>
                 </tr>
                 <tr>
                     <td>Num (float 3 dec) <= 5000000:</td>
                     <td>
                         <input id="id_id_num_float_3d_max"
                                name="num_float_3d_max"
                                autocomplete="off"
                                size="43"
                                value=""
                                maxlength="100"
                                data-format="float_3d"
                                data-validation="float_3d"
                                data-validation-max="5000000"/>
                     </td>
                 </tr>
                 <tr style="background-color:#f0f0f0">
                     <td>Num (float 3 dec) >= 0.001 <= 5000000:</td>
                     <td>
                         <input id="id_num_float_3d_min_max"
                                name="num_float_3d_min_max"
                                autocomplete="off"
                                size="43"
                                value=""
                                maxlength="100"
                                data-format="float_3d"
                                data-validation="float_3d"
                                data-validation-min-max="0.001-5000000"/>
                     </td>
                 </tr>
                 <tr>
                     <td>Date:</td>
                     <td>
                         <input name="fecha"
                                type="text"
                                id="id_fecha"
                                value=""
                                data-constraints="date"
                                data-validation="date"
                                maxlength="10"/>
                      </td>
                 </tr>
                 <tr style="background-color:#f0f0f0">
                     <td>Date (min 2018-01-01):</td>
                     <td>
                         <input name="fecha_min"
                                type="text"
                                id="id_fecha_min"
                                value=""
                                data-constraints="date"
                                data-validation="date"
                                data-validation-min="2018-01-01"
                                maxlength="10"/>
                     </td>
                 </tr>
                 <tr>
                     <td>Date (max 2016-12-31):</td>
                     <td>
                         <input name="fecha_max"
                                type="text"
                                id="id_fecha_max" 
                                value=""
                                data-constraints="date"
                                data-validation="date"
                                data-validation-max="2016-12-31"
                                maxlength="10"/>
                     </td>
                 </tr>
                 <tr style="background-color:#f0f0f0">
                     <td>Date (min-max 2016-12-31 / 2018-01-01):</td>
                     <td>
                         <input name="fecha_min_max"
                                type="text"
                                id="id_fecha_min_max"
                                value=""
                                data-constraints="date"
                                data-validation="date"
                                data-validation-min-max="2016-12-31/2018-01-01"
                                maxlength="10"/>
                     </td>
                 </tr>
                 <tr>
                     <td>Time:</td>
                     <td> 
                         <input id="id_time"
                                name="time"
                                type="text"
                                data-format="uppercase"
                                data-constraints="time"
                                data-validation="time"
                                maxlength="8"/>
                     </td>
                 </tr>
                 <tr style="background-color:#f0f0f0">
                     <td>Time (min 09:00:AM):</td>
                     <td> 
                         <input id="id_time_min"
                                name="time_min"
                                type="text"
                                data-format="uppercase"
                                data-constraints="time"
                                data-validation="time"
                                data-validation-min="09:00:AM"
                                maxlength="8"/>
                     </td>
                 </tr>
                 <tr>
                     <td>Time (max 03:00:PM):</td>
                     <td> 
                         <input id="id_time_max"
                                name="time_max"
                                type="text"
                                data-format="uppercase"
                                data-constraints="time"
                                data-validation="time"
                                data-validation-max="03:00:PM"
                                maxlength="8"/>
                     </td>
                 </tr>
                 <tr style="background-color:#f0f0f0">
                     <td>Time (min-max 09:00:AM - 03:00:PM):</td>
                     <td> 
                         <input id="id_time_min_max"
                                name="time_min_max"
                                type="text"
                                data-format="uppercase"
                                data-constraints="time"
                                data-validation="time"
                                data-validation-min-max="09:00:AM-03:00:PM"
                                maxlength="8"/>
                     </td>
                 </tr>
                 <tr>
                     <td>Length (10 char):</td>
                     <td>
                         <input id="id_length"
                                name="length"
                                autocomplete="off"
                                size="43"
                                value=""
                                maxlength="100"
                                placeholder="Length (10 char)"
                                data-validation="length"
                                data-validation-length="10"/>
                     </td>
                 </tr>
                 <tr style="background-color:#f0f0f0">
                     <td>Length (5 min):</td>
                     <td>
                         <input id="id_length_min"
                                name="length_min"
                                autocomplete="off"
                                size="43"
                                value=""
                                maxlength="100"
                                placeholder="Length (5 min)"
                                data-validation="length"
                                data-validation-min="5"/>
                     </td>
                 </tr>
                 <tr>
                     <td>Length (10 max):</td>
                     <td>
                         <input id="id_length_max"
                                name="length_max"
                                autocomplete="off"
                                size="43"
                                value=""
                                maxlength="100"
                                placeholder="Length (10 max)"
                                data-validation="length"
                                data-validation-max="10"/>
                     </td>
                 </tr>
                 <tr style="background-color:#f0f0f0">
                     <td>Length (5 min - 10 max):</td>
                     <td>
                         <input id="id_length_min_max"
                                name="length_min_max"
                                autocomplete="off"
                                size="43"
                                value=""
                                maxlength="100"
                                placeholder="Length (5 min - 10 max)"
                                data-validation="length"
                                data-validation-min-max="5-10"/>
                     </td>
                 </tr>
                <tr>
                     <td>Required:</td>
                     <td>
                         <input id="id_required"
                                name="required"
                                autocomplete="off"
                                size="43"
                                style="width: 99%;"
                                value=""
                                maxlength="100"
                                data-validation="required"
                                placeholder="Required"/>
                     </td>
                 </tr>
                 <tr style="background-color:#f0f0f0">
                     <td>Required (number):</td>
                     <td>
                         <input id="id_required_number"
                                name="required_number"
                                autocomplete="off"
                                size="43"
                                style="width: 99%;"
                                value=""
                                maxlength="100"
                                data-constraints="number"
                                data-validation="required"
                                placeholder="Required (number)"/>
                     </td>
                 </tr>
                 <tr>
                     <td>Required (uppercase letters):</td>
                     <td>
                         <input id="id_required_letter_upper"
                                name="required_letter_upper"
                                autocomplete="off"
                                size="43"
                                value=""
                                maxlength="100"
                                data-format="uppercase"
                                data-constraints="letter"
                                data-validation="required"
                                placeholder="Required (uppercase letters)"/>
                     </td>
                 </tr>
                 <tr style="background-color:#f0f0f0">
                     <td>Required (lowercase letters):</td>
                     <td>
                         <input id="id_required_letter_lower"
                                name="required_letter_lower"
                                autocomplete="off"
                                size="43"
                                value=""
                                maxlength="100"
                                data-format="lowercase"
                                data-constraints="letter"
                                data-validation="required"
                                placeholder="Required (lowercase letters)"/>
                     </td>
                 </tr>
                  <tr>
                     <td>Required (code):</td>
                     <td>
                         <input id="id_required_code"
                                name="required_code"
                                autocomplete="off"
                                size="43"
                                value=""
                                maxlength="100"
                                data-format="uppercase"
                                data-constraints="code"
                                data-validation="required"
                                placeholder="Required (code)"/>
                     </td>
                 </tr>
                 <tr style="background-color:#f0f0f0">
                     <td>Required (Full Name):</td>
                     <td>
                         <input id="id_required_fullname"
                                name="required_fullname"
                                autocomplete="off"
                                size="43"
                                value=""
                                maxlength="100"
                                data-format="uppercase"
                                data-constraints="fullname"
                                data-validation="required"
                                placeholder="Required (Full Name)"/>
                     </td>
                 </tr>
                 <tr>
                     <td>Required (Firm Name):</td>
                     <td>
                         <input id="id_required_firmname"
                                name="required_firmname"
                                autocomplete="off"
                                size="43"
                                value=""
                                maxlength="100"
                                data-format="uppercase"
                                data-constraints="firmname"
                                data-validation="required"
                                placeholder="Required (Firm Name)"/>
                     </td>
                 </tr>
                 <tr style="background-color:#f0f0f0">
                     <td>Required (User Name):</td>
                     <td>
                         <input id="id_required_username"
                                name="required_username"
                                autocomplete="off"
                                size="43"
                                value=""
                                maxlength="100"
                                data-format="lowercase"
                                data-constraints="username"
                                data-validation="required"
                                placeholder="Required (User Name)"/>
                     </td>
                 </tr>
                 <tr>
                     <td>Email:</td>
                     <td>
                         <input id="id_email"
                                name="email"
                                autocomplete="off"
                                size="43"
                                value=""
                                maxlength="100"
                                data-format="lowercase"
                                data-constraints="email"
                                data-validation="email"
                                placeholder="email@dominio.ext"/>
                     </td>
                 </tr>
                 <tr style="background-color:#f0f0f0">
                     <td>Radio:</td>
                     <td>
                         <input type="radio"
                                id="id_radio"
                                name="radio"
                                data-validation="radio"
                                value="Val1"/>Value 1
                         <input type="radio"
                                id="id_radio"
                                name="radio"
                                data-validation="radio"
                                value="Val2"/>Value 2
                         <input type="radio"
                                id="id_radio"
                                name="radio"
                                data-validation="radio"
                                value="Val3"/>Value 3
                     </td>
                 </tr>
                 <tr>
                     <td>Check Box:</td>
                     <td aling="left">
                         <input type="checkbox"
                                id="id_boxcheck"
                                name="boxcheck"
                                data-validation="checkbox"/>
                     </td>
                 </tr>
                 <tr style="background-color:#f0f0f0">
                     <td>Text Area:</td>
                     <td>
                         <textarea id="id_areatext"
                                   name="areatext"
                                   rows="3"
                                   cols="55"
                                   placeholder="Textarea"
                                   data-format="uppercase"
                                   data-constraints="textarea"
                                   data-validation="textarea"
                                   data-format="uppercase"></textarea>
                     </td>
                 </tr>
                 <tr>
                     <td>Select Options:</td>
                     <td>
                         <select id="id_select" name="select" data-validation="select">
                             <option value="null" selected>Select an option...</option>
                             <option value="1">Option-1</option>
                             <option value="2">Option-2</option>
                             <option value="3">Option-3</option>
                          </select>  
                      </td>
                  </tr>
                 <tr style="background-color:#f0f0f0">
                      <td>Select Options Small:</td>
                      <td>
                         <select id="id_select_small" name="select_small" data-validation="select-small">
                             <option value="null" selected>Select an option...</option>
                             <option value="1">Opt-1</option>
                             <option value="2">Opt-2</option>
                             <option value="3">Opt-3</option>
                         </select>
                      </td>
                  </tr>
                  <tr>
                      <td>Select Multiple:</td>
                      <td>
                      <div style="float:left;">
                          <select id="objList"
                                  name="objList"
                                  style="cursor:pointer;" 
                                  multiple 
                                  size="7" 
                                  onDblClick="move('right', document.getElementById('objList'), document.getElementById('objSelected')); 
                                             getValues(document.getElementById('objSelected'), document.getElementById('strArr'));
                                             valObj(document.getElementById('objSelected'));">
                                 <option value="1">Option-1</option>
                                 <option value="2">Option-2</option>
                                 <option value="3">Option-3</option>
                         </select>
                     </div>
                     <div style="float:left;">
                         <input type="button" 
                                value=">>>"
                                style="cursor:pointer;"
                                onClick="move('right', document.getElementById('objList'), document.getElementById('objSelected')); 
                                         getValues(document.getElementById('objSelected'), document.getElementById('strArr'));
                                         valObj(document.getElementById('objSelected'));"/>
                         <input type="button" 
                                value="<<<"
                                style="cursor:pointer;"
                                onClick="move('left', document.getElementById('objList'), document.getElementById('objSelected')); 
                                         getValues(document.getElementById('objSelected'), document.getElementById('strArr'));
                                         valObj(document.getElementById('objSelected'));"/>
                     </div>
                     <div style="float:left;">
                         <select id="objSelected"
                                 name="objSelected"
                                 style="cursor:pointer;"  
                                 multiple
                                 size="7"
                                 data-validation="select-multiple"
                                 onDblClick="move('left', document.getElementById('objList'), document.getElementById('objSelected')); 
                                             getValues(document.getElementById('objSelected'), document.getElementById('strArr'));
                                             valObj(document.getElementById('objSelected'));">
                         </select>
                         <input id="strArr" name="strArr" type="hidden" value="">
                     </div>
                 </td>  
             </tr>
             </table>
         </div>
         <br/>
         <button id="id_inicializar" type="button" onClick="inicializarObjs();">Inicializar</button>
         <button id="id_guardar" type="button" onClick="valEnvio();">Guardar</button>
     </div> 
 </section>
 </body>
 </html>


A continuación mostramos el contenido del archivo inicio.js y su función con el mismo nombre. Dicha función es invocada desde el evento onload() del elemento <body>.

Dentro de este archivo hay 3 funciones declaradas:

  • inicio()
  • inicializarObjs()
  • valEnvio()

Primero note que, en la función inicio() hacemos uso de la función DOM.ready() para invocar a las funciones inicializarObjs(), formatData(), constraintsData() y validateData(). A excepción de inicializarObjs(), todas las demás están declaradas en el archivo formData.js

Luego observe que, dentro de inicializarObjs() tenemos a initObjs() y initObjsSelectMultiple(), ambas también declaradas en el archivo validateData.js.

Finalmente, en la función valEnvio() tenemos la función validateObjs(). Se trata de la función que valida el contenedor, antes de enviar los datos al servidor. Esta última, también está declaradas en el archivo validateData.js.

inicio.js

 function inicio()
 {
     DOM.ready( function()
     {
         var obj = document.getElementById( "contenido" );
         inicializarObjs();
         formatData( obj );
         constraintsData( obj );
         validateData( obj );
     } );
 }

 function inicializarObjs()
 {
     initObjs( document.getElementById( "contenido" ) );
     initObjsSelectMultiple( document.getElementById( "objList" ),
                             document.getElementById( "objSelected" ) );
 }

 function valEnvio()
 {
     if ( validateObjs( document.getElementById( "contenido" ) ) ) {
         alert( "Exito: Formulario validado correctamente..." );
     }
 }


Si aún no tiene conocimiento de la funcion DOM.ready() ubicada en el erchivo dom.js le recomendamos que la conosca.

Su utilidad es la de ejecutar funciones, una vez cargada en su totalidad una página web (Document Object Model).


El siguiente archivo, posee dos funciones que manipulan colecciones de elementos seleccionados (a criterio), para asignarles eventos y/o atributos.

Dichas funciones son invocadas desde las funciones formatData(), constraintsData() y validateData(), respectivamente, una vez que el DOM.ready() esté listo, las cuales se encuentran en el archivo formData.js

Estas dos funciones ( addSetAttributeInGroup() y addEventListenerInGroup() ) reciben el arreglo que contiene la colección de elementos seleccionados, para asignarles eventos y/o atributos, como corresponda.

array.js

 function addSetAttributeInGroup(aObj,  attribute, property)
 {
     for ( var i = 0; i < aObj.length; i++ )
         aObj[i].setAttribute( attribute, property );
 }

 function addEventListenerInGroup(aObj, aEvent, oFun)
 {
     for ( var i = 0; i < aObj.length; i++ )
         for ( var j = 0; j < aEvent.length; j++ )
             aObj[i].addEventListener( aEvent[j], oFun);
 }


Veamos ahora el archivo validateData.js, este código es la razón de ser de este apartado. Si usted declara en su contenedor ( <div>, <table>, <section>, etc.), cualquier elemento de entrada de datos (<input> - incluyendo radio y checkbox -, <select> y/o <textarea>) con los atributos respectivos, este archivo se encargará de formatear, inicializar, restringir y validar su contenedor con JavasCript (sin jQuery).

Preste especial atención, en este archivo a las funciones aquí declaradas, e invocadas desde la funciones inicio() y valEnvio(), en el archivo inicio.js respectivamente.

Hablamos de:

  • constraintsData()
  • formatData()
  • validateData()
  • validateObjs()
  • initObjs()
  • initObjsSelectMultiple()
validateData.js

 /*Autor: Ernesto Jiménez @fdsoil */

 /** Restringe las entradas de datos contenidos dentro de un elemento HTML.
 * Los elementos contenedores pueden ser por ejemplo: FORM, DIV, TABLE, SECTION...
 * Las entradas son recibidas en elementos tales como INPUT, SELECT y TEXTAREA.
 * Para que estas entradas sean RESTRINGIDAS deben tener el atributo respectivo 'data-constraints'.
 * Ver también: {@link formatData}, {@link validateData}, {@link initObjs}.
 * @param obj (object) Elemento contenedor de las entradas de datos. Ejemplo: FORM, DIV, TABLE, SECTION....*/
 function constraintsData(obj)
 {
     var aEvents = [ "onkeypress" ];
     var fNoBlankSpaceLeft = " && ((this.value.length==0 && ((document.all)?event.keyCode:event.which)==32)?false:true);"; 
     this.acceptOnlyRegExp = function( e, strRegExp )
     {
         var tecla = ( document.all ) ? e.keyCode : e.which;
         if ( tecla == 8 )
             return true;
         var patron = strRegExp;
         var te;
         te = String.fromCharCode( tecla );
         return patron.test( te );
     }
     /* Accepts Only Letters. */
     var fLetter = "return acceptOnlyRegExp( event, /[a-zA-Z]/ );";
     addSetAttributeInGroup( obj.querySelectorAll( "[data-constraints=letter]" ), aEvents, fLetter );
     /* Accepts Only Numbers. */
     var fNumber = "return acceptOnlyRegExp( event, /[0-9]/ );";
     addSetAttributeInGroup( obj.querySelectorAll( "[data-constraints=number]" ), aEvents, fNumber );
     /* Accepts Only Numbers and Letters. */
     var fCode = "return acceptOnlyRegExp( event, /[0-9a-zA-Z]/ );";
     addSetAttributeInGroup( obj.querySelectorAll( "[data-constraints=code]" ), aEvents, fCode );
     /* Accepts Letters, Blanks, Points and Commas. */
     var fFullName = "return acceptOnlyRegExp( event, /[a-zñA-ZÑ\\s.,]/ )" + fNoBlankSpaceLeft;
     addSetAttributeInGroup( obj.querySelectorAll( "[data-constraints=fullname]" ), aEvents, fFullName );
     /* Accepts Letters, Blanks, Points, Commas and Parentheses. */
     var fTextArea = "return acceptOnlyRegExp( event, /[0-9a-zñA-ZÑ\\s.,()]/ )" + fNoBlankSpaceLeft;
     addSetAttributeInGroup( obj.querySelectorAll( "[data-constraints=textarea]" ), aEvents, fTextArea );
     /* Accepts Letters, Blanks, Points, Commas, Parentheses and Ampersand. */
     var fFirmName = "return acceptOnlyRegExp( event, /[0-9a-zA-Z\\s.,()&]/ )" + fNoBlankSpaceLeft;
     addSetAttributeInGroup( obj.querySelectorAll( "[data-constraints=firmname]" ), aEvents, fFirmName);
     /* Accepts Numbers, Letters, Points And Underscore. */
     var fUserName = "return acceptOnlyRegExp( event, /[0-9a-zA-Z._]/ );";
     addSetAttributeInGroup( obj.querySelectorAll( "[data-constraints=username]"), aEvents, fUserName );
     /* Accepts Numbers, Letters, Points, Underscore, Guión And Arroba. */
     var fEmail = "return acceptOnlyRegExp( event, /[0-9a-zA-Z.@_-]/ );";
     addSetAttributeInGroup( obj.querySelectorAll( "[data-constraints=email]" ), aEvents, fEmail);
     /* Accepts Numbers, 2 Points, Aa, Pp and Mm. */
     var fTime = "return acceptOnlyRegExp( event, /[0-9AaMmPp:]/ );";
     addSetAttributeInGroup( obj.querySelectorAll( "[data-constraints=time]" ), aEvents, fTime);
     /* Accepts Numbers and guión ("-"). */
     var fDate = "return acceptOnlyRegExp( event, /[0-9-]/ );";
     addSetAttributeInGroup( obj.querySelectorAll( "[data-constraints=date]" ), aEvents, fDate);
 } 

 /** Formatea las entradas de datos contenidos dentro de un elemento HTML.
 * Los elementos contenedores pueden ser por ejemplo: FORM, DIV, TABLE, SECTION...
 * Las entradas son recibidas en elementos tales como INPUT, SELECT y TEXTAREA.
 * Para que estas entradas sean formateadas deben tener el atributo respectivo 'data-format'.
 * Ver también: {@link constraintsData}, {@link validateData}, {@link initObjs}.
 * @param obj (object) Elemento contenedor de las entradas de datos. Ejemplo: FORM, DIV, TABLE, SECTION....*/
 function formatData(obj)
 {
     var aEvents = [ "keyup" ];
     addEventListenerInGroup
     (
         obj.querySelectorAll("[data-format=uppercase]"), aEvents, function(event){this.value = this.value.toUpperCase();}
     );
     addSetAttributeInGroup(obj.querySelectorAll("[data-format=uppercase]"), "style" , "text-transform: uppercase");

     addEventListenerInGroup
     (
         obj.querySelectorAll("[data-format=lowercase]"), aEvents, function(event){this.value = this.value.toLowerCase();}
     );
     addSetAttributeInGroup(obj.querySelectorAll("[data-format=lowercase]"), "style" , "text-transform: lowercase");

     aEvents = [ "onkeypress" ];
     var fInt = "return formato_numeric(this, '.', ',', event);";
     addSetAttributeInGroup(obj.querySelectorAll("[data-format=integer]"), aEvents, fInt);
     addSetAttributeInGroup(obj.querySelectorAll("[data-format=integer]"), [ "style" ], "text-align:right");

     var fFloat = "return formato_float(this, '.', ',', event);";
     addSetAttributeInGroup(obj.querySelectorAll("[data-format=float]"), aEvents, fFloat);
     addSetAttributeInGroup(obj.querySelectorAll("[data-format=float]"), [ "style" ], "text-align:right");

     var fFloat3d = "return formato_float_3d(this, '.', ',', event);";
     addSetAttributeInGroup(obj.querySelectorAll("[data-format=float_3d]"), aEvents, fFloat3d);
     addSetAttributeInGroup(obj.querySelectorAll("[data-format=float_3d]"), [ "style" ], "text-align:right");
 }

 /** Agrega eventos de validación a las entradas de datos contenidos dentro de un elemento HTML.
 * Los elementos contenedores pueden ser por ejemplo: FORM, DIV, TABLE, SECTION...
 * Las entradas son recibidas en elementos tales como INPUT, SELECT y TEXTAREA.
 * Para agregar los eventos de validación, deben tener el atributo respectivo 'data-validation'.
 * Ver también: {@link constraintsData}, {@link formatData}, {@link initObjs}.
 * @param obj (object) Elemento contenedor de las entradas de datos. Ejemplo: FORM, DIV, TABLE, SECTION....*/
 function validateData(obj)
 {
     var aEventsInput = [ "keyup", "blur", "focus" ];
     var aEventsSelect = [ "change", "blur"];
     var aEventsSelectMultiple = [ "dblclick", "blur", "focus" ];
     var aEventsRadio = [ "click" ];
     var oFun = function() { valObj(this); };
     var oFunRadio = function() { valObjs(this.name); };
     addEventListenerInGroup(obj.querySelectorAll("input[data-validation=required]"), aEventsInput, oFun);
     addEventListenerInGroup(obj.querySelectorAll("input[data-validation=length]"), aEventsInput, oFun);
     addEventListenerInGroup(obj.querySelectorAll("input[data-validation=email]"), aEventsInput, oFun);
     addEventListenerInGroup(obj.querySelectorAll("input[data-validation=float]"), aEventsInput, oFun);
     addEventListenerInGroup(obj.querySelectorAll("input[data-validation=float_3d]"), aEventsInput, oFun);
     addEventListenerInGroup(obj.querySelectorAll("input[data-validation=integer]"), aEventsInput, oFun);
     addEventListenerInGroup(obj.querySelectorAll("input[data-validation=date]"), aEventsInput, oFun);
     addEventListenerInGroup(obj.querySelectorAll("input[data-validation=time]"), aEventsInput, oFun);
     addEventListenerInGroup(obj.querySelectorAll("input[data-validation=radio]"), aEventsRadio, oFunRadio);
     addEventListenerInGroup(obj.querySelectorAll("textarea[data-validation=textarea]"), aEventsInput, oFun);
     addEventListenerInGroup(obj.querySelectorAll("select[data-validation=select]"), aEventsSelect, oFun);
     addEventListenerInGroup(obj.querySelectorAll("select[data-validation=select-small]"), aEventsSelect, oFun);
     addEventListenerInGroup(obj.querySelectorAll("select[data-validation=select-multiple]"), aEventsSelectMultiple, oFun);
 }

 /** Valida las entradas de datos contenidos dentro de un elemento HTML.
 * Los elementos contenedores pueden ser por ejemplo:
 * FORM, DIV, TABLE...
 * Las entradas son recibidas en objetos tales como INPUT, SELECT y TEXTAREA.
 * Para que estas entradas sean validadas deben tener los atributos respectivos definidos en jQryValidateData().
 * @param obj (object) Elemento HTML contenedor de las entradas de datos.
 * @return (boolean) Devuelve TRUE si no está definida la clase 'error' (css) dentro del contenedor (elemento HTML),
 * de lo contrario devuelve FALSE.*/
 function validateObjs(obj)
 {
     var objsSelect = obj.getElementsByTagName( "select" );
     for ( var i = 0; i < objsSelect.length; i++ )
        valObj( objsSelect[i] );
     var objsTextArea = obj.getElementsByTagName( "textarea" );
     for ( var i = 0; i < objsTextArea.length; i++ )
        valObj( objsTextArea[i], true );
     var objsInput = obj.getElementsByTagName( "input" );
     var objsRadioCheck = [];
     var k = 0;
     for ( var i = 0; i < objsInput.length;i++)
         if ( objsInput[i].getAttribute( "type" ) != "button"
         && objsInput[i].getAttribute( "type" ) != "submit"
         && objsInput[i].getAttribute( "type" ) != "radio"
         && objsInput[i].getAttribute( "type" ) != "checkbox"
         && objsInput[i].getAttribute( "data-validation" ) != null )
             valObj( objsInput[i], true );
         else if ( objsInput[i].getAttribute( "type" ) == "radio" )
             objsRadioCheck[k++] = objsInput[i];
     if ( objsRadioCheck.length > 0 ) {
         var key = 0;
         var keyAux = 0;
         var strRadioCheckName = objsRadioCheck[0].name;
         var mObjsRadioCheck = [];
         mObjsRadioCheck[key] = [];
         mObjsRadioCheck[key][keyAux++] = objsRadioCheck[0];
         for ( var i = 1; i < objsRadioCheck.length; i++ )
             if ( strRadioCheckName == objsRadioCheck[i].name ) {
                while ( strRadioCheckName == objsRadioCheck[i].name ) {
                     mObjsRadioCheck[key][keyAux++] = objsRadioCheck[i++];
                     if ( i == objsRadioCheck.length )
                         break;
                 }
                 if ( i == objsRadioCheck.length )
                     break;
                 else {
                     strRadioCheckName = objsRadioCheck[i--].name;
                     keyAux = 0;
                     mObjsRadioCheck[++key] = [];
                 }
             }
             for ( var i = 0; i < mObjsRadioCheck.length; i++ )
                 valObjsRadioCheck( mObjsRadioCheck[i] );
     }
     return ( obj.getElementsByClassName( "error" ).length == 0 );
 }

 /** Valida el dato contenido en un elemento HTML. Dicho elemento puede ser: INPUT, SELECT o TEXTAREA.
 * Para que el elemento sea validado debe tener el atributo respectivo definidos en jQryValidateData().
 * Si el elemento no cumple con la validación, la clase 'error' (css) es asignada al elemento. De lo contrario
 * dicha clase es removida.
 * @param obj (object) Elemento HTML contenedor del dato.*/
 function valObj(obj, inGroup = false)
 {
     obj.value = inGroup?obj.value.replace(/([\ \t]+(?=[\ \t])|^\s+|\s+$)/g, ''):obj.value.replace(/([\ \t]+(?=[\ \t])|^\s+)/g, '');
     if ( obj.getAttribute( "data-validation" ) == "required" )
         ( obj.value == '' ) ? displayErrorMsg( obj, ' Campo Requerido' ) : removeErrorMsg(obj);
     else if ( obj.getAttribute( "data-validation" ) == "length" ) {
         if ( obj.getAttribute( "data-validation-length" ) != null )
             ( obj.value.length != obj.getAttribute( "data-validation-length" ) )
             ? displayErrorMsg( obj, ' Deben ser ' + obj.getAttribute( "data-validation-length" ) + ' caracteres ')
             : removeErrorMsg(obj);
         else if ( obj.getAttribute( "data-validation-min" ) != null )
             ( obj.value == '' || obj.value.length < obj.getAttribute( "data-validation-min" ) )
             ? displayErrorMsg( obj, ' Debe ser mayor o igual a ' + obj.getAttribute( "data-validation-min" ) + ' caracteres ')
             : removeErrorMsg(obj);
         else if ( obj.getAttribute( "data-validation-max" ) != null )
             ( obj.value == '' || obj.value.length > obj.getAttribute( "data-validation-max" ) )
             ? displayErrorMsg( obj, ' Debe ser menor o igual a ' + obj.getAttribute( "data-validation-max" ) + ' caracteres ')
             : removeErrorMsg(obj);
         else if ( obj.getAttribute( "data-validation-min-max" ) != null ) {
             var arr = obj.getAttribute( "data-validation-min-max" ).split('-');
             ( obj.value == '' || ( obj.value.length < arr[0] || obj.value.length > arr[1] ) )
             ? displayErrorMsg( obj, ' Debe ser entre '
                 + obj.getAttribute( "data-validation-min-max" ).replace('-', ' y ') + ' caracteres ')
             : removeErrorMsg(obj);
         }
     } else if ( obj.getAttribute( "data-validation" ) == "integer" )
         if ( obj.getAttribute( "data-validation-min" ) != null )
             ( valInt(obj) == false )
             ? displayErrorMsg( obj, ' Indique un valor numérico' )
             : !( valMoreThan(obj) )
                 ? displayErrorMsg( obj, ' Indique número mayor o igual a ' + obj.getAttribute( "data-validation-min" ) )
                 : removeErrorMsg(obj);
         else if ( obj.getAttribute( "data-validation-max" ) != null )
             ( valInt(obj) == false )
             ? displayErrorMsg( obj, ' Indique un valor numérico' )
             : !( valLessThan(obj) )
                 ? displayErrorMsg( obj, ' Indique número menor o igual a ' + obj.getAttribute( "data-validation-max" ) )
                 :removeErrorMsg(obj);
         else if ( obj.getAttribute( "data-validation-min-max" ) != null )
             ( valInt(obj) == false)
             ? displayErrorMsg( obj, ' Indique un valor numérico' )
             : !( valMoreAndLessThan(obj) )
                 ? displayErrorMsg( obj, ' Indique número entre ' + obj.getAttribute( "data-validation-min-max" ).replace('-', ' y '))
                 : removeErrorMsg(obj);
         else
             (valInt(obj)==false)?displayErrorMsg(obj, ' Indique valor numérico' ):removeErrorMsg(obj);
     else if ( obj.getAttribute( "data-validation" ) == "float" || obj.getAttribute( "data-validation" ) == "float_3d" )
         if ( obj.getAttribute( "data-validation-min" ) != null )
             ( valFloat(obj) == false )
             ? displayErrorMsg( obj, ' Indique un valor numérico' )
             : !( valMoreThan(obj) )
                 ? displayErrorMsg( obj, ' Indique número mayor o igual a ' + obj.getAttribute( "data-validation-min" ) )
                 : removeErrorMsg(obj);
         else if ( obj.getAttribute( "data-validation-max" ) != null )
             ( valFloat(obj) == false )
             ? displayErrorMsg( obj, ' Indique un valor numérico' )
             : !( valLessThan(obj) )
                 ? displayErrorMsg( obj, ' Indique número menor o igual a ' + obj.getAttribute( "data-validation-max" ) )
                 : removeErrorMsg(obj);
         else if ( obj.getAttribute( "data-validation-min-max" ) != null )
             ( valFloat(obj) == false )
             ? displayErrorMsg( obj, ' Indique un valor numérico' )
             : !( valMoreAndLessThan(obj) )
                 ? displayErrorMsg( obj, ' Indique número entre ' + obj.getAttribute( "data-validation-min-max" ).replace('-', ' y '))
                 : removeErrorMsg(obj);
         else
             ( valFloat(obj) == false )
             ? displayErrorMsg( obj, ' Indique valor numérico' )
             : removeErrorMsg(obj);
     else if ( obj.getAttribute( "data-validation" ) == "date" )
         if ( obj.getAttribute( "data-validation-min" ) != null )
             ( valDate(obj) == false )
             ? displayErrorMsg( obj, ' Formato de Fecha Invalida' )
             : !( valMoreThan(obj) )
                 ? displayErrorMsg( obj, ' Indique fecha mayor o igual a ' + obj.getAttribute( "data-validation-min" ) )
                 : removeErrorMsg(obj);
         else if ( obj.getAttribute( "data-validation-max" ) != null )
             ( valDate(obj) == false )
             ? displayErrorMsg( obj, ' Formato de Fecha Invalida' )
                 : ! ( valLessThan(obj) )
                 ? displayErrorMsg( obj, ' Indique fecha menor o igual a ' + obj.getAttribute( "data-validation-max" ) )
                 : removeErrorMsg(obj);
         else if ( obj.getAttribute( "data-validation-min-max" ) != null )
             ( valDate(obj) == false )
             ? displayErrorMsg( obj, ' Formato de Fecha Invalida' )
             : !( valMoreAndLessThan(obj) )
                 ? displayErrorMsg( obj, ' Indique fecha entre ' + obj.getAttribute( "data-validation-min-max" ).replace('/', ' y '))
                 : removeErrorMsg(obj);
         else
             ( valDate(obj) ==false )
             ? displayErrorMsg(obj, ' Formato de Fecha Invalida' )
             :removeErrorMsg(obj);
     else if ( obj.getAttribute( "data-validation" ) == "time" )
         if ( obj.getAttribute( "data-validation-min" ) != null )
             ( valTime(obj) == false )
             ? displayErrorMsg( obj, ' Formato de Hora Invalido' )
             : !( valMoreThan(obj) )
                 ? displayErrorMsg( obj, ' Indique Hora mayor o igual a ' + obj.getAttribute( "data-validation-min" ) )
                 : removeErrorMsg(obj);
         else if ( obj.getAttribute( "data-validation-max" ) != null )
             ( valTime(obj) == false )
             ? displayErrorMsg( obj, ' Formato de Hora Invalido' )
             : !( valLessThan(obj) )
                 ? displayErrorMsg( obj, ' Indique Hora menor o igual a ' + obj.getAttribute( "data-validation-max" ) )
                 :removeErrorMsg(obj);
         else if ( obj.getAttribute( "data-validation-min-max" ) != null )
             ( valTime(obj) == false )
             ? displayErrorMsg( obj, ' Formato de Hora Invalido' )
             : !( valMoreAndLessThan(obj) )
                 ? displayErrorMsg( obj, ' Indique Hora entre ' + obj.getAttribute( "data-validation-min-max" ).replace('/', ' y '))
                 : removeErrorMsg(obj);
         else
             ( valTime(obj) == false )
             ? displayErrorMsg( obj, ' Formato de Hora Invalido' )
             : removeErrorMsg(obj);
     else if ( obj.getAttribute( "data-validation" ) == "email" )
         ( valEmail(obj.value) == false ) ? displayErrorMsg(obj, 'Formato de Correo Invalido' ) : removeErrorMsg(obj);
     else if ( obj.getAttribute( "data-validation" ) == "url" )
         ( valURL(obj.value) == false ) ? displayErrorMsg( obj, 'Formato de URL Invalido' ) : removeErrorMsg(obj);
     else if ( obj.getAttribute( "data-validation" ) == "select" )
         ( obj.selectedIndex == 0 ) ? displayErrorMsg( obj, 'Seleccione un Item' ) : removeErrorMsg(obj);
     else if ( obj.getAttribute( "data-validation" ) == "select-small" )
         ( obj.selectedIndex==0 ) ? displayErrorMsg( obj, 'Selec...' ): removeErrorMsg(obj);
     else if ( obj.getAttribute( "data-validation" ) == "select-multiple" )
         ( obj.length==0 ) ? displayErrorMsg( obj, 'Seleccionar Item(s)' ) : removeErrorMsg(obj);
     else if ( obj.getAttribute( "data-validation" ) == "textarea" )
         ( obj.value == '') ? displayErrorMsg(obj, 'Texto Requerido' ) : removeErrorMsg(obj);
 }

 /** Valida que un elemento TABLE, tenga como mínimo el número de filas (elemento TR)
 * definida con el atributo (data-validation-min). Para que la tabla sea validada debe tener también
 * el atributo: (data-validation='table'). Si el elemento no cumple con la validación, la clase 'error'
 * (css) es asignada, de lo contrario, es removida.
 * @param obj (object) Elemento TABLE. Tabla a ser validada.*/
 function valObjTable(obj)
 {
     if ( obj.getAttribute( "data-validation" ) == "table" ) {
         if ( valTable( obj, obj.getAttribute( "data-validation-min" ) ) == false ) {
             displayErrorMsgTable( obj, 'Debe agregar mínimo ' + obj.getAttribute( "data-validation-min" ) + ' Item(s)' );
             return false;
         } else {
             removeErrorMsgTable(obj);
             return true;
         }
     }
 }

 /** Valida que el valor de un elemento sea tipo FLOAT (double precision).
 * @param obj (object) Elemento que contiene el valor a ser validado.
 * @return (boolean) Devuelve FALSE si no cumple con la condición, de lo contrario devuelve TRUE.*/
 function valFloat(obj)
 {
     return ( isNaN( parseFloat( obj.value.replace(/\./g, '').replace(',', '.') ) ) ) ? false : true;
 }

 /** Valida que el valor de un elemento sea tipo INTEGER.
 * @param obj (object) Elemento que contiene el valor a ser validado.
 * @return (boolean) Devuelve FALSE si no cumple con la condición, de lo contrario devuelve TRUE.*/
 function valInt(obj)
 {
     var x = obj.value.replace(/\./g, '');
     var y = parseInt(x);
     if ( isNaN(y) )
         return false;
     return x == y && x.toString() == y.toString();
 }

 /** Valida que el valor de un elemento sea mayor o igual que el contenido del atributo 'data-validation-min'.
 * Para que el elemento sea validado debe tener también el atributo: ('data-validation') con su valor respectivo
 * ('integer'; 'float'; 'date'; 'time').
 * @param obj (object) Elemento que contiene el valor a ser validado.
 * @return (boolean) Devuelve FALSE si no cumple con la condición, de lo contrario devuelve TRUE.*/
 function valMoreThan(obj)
 {
     if ( obj.getAttribute( "data-validation" ) == "integer"
     || obj.getAttribute( "data-validation" ) == "float"
     || obj.getAttribute( "data-validation" )=="float_3d" )
         return ( ( obj.value.replace(/\./g, '').replace(',', '.') * 1 ) >= ( obj.getAttribute( "data-validation-min" ) * 1 ) );
     else if ( obj.getAttribute( "data-validation" ) == "date" )
         return ( ( obj.value.replace(/\-/g, '') * 1 ) >= ( obj.getAttribute( "data-validation-min" ).replace(/\-/g, '') * 1 ) );
     else if ( obj.getAttribute( "data-validation" ) == "time")
         return ( ( chkHour00To24( timeNormalToMilitar( obj.value ) ).replace(/\:/g, '') * 1 )
             >= ( chkHour00To24( timeNormalToMilitar( obj.getAttribute( "data-validation-min" ) ) ).replace(/\:/g, '') * 1 ) );
 }

 /** Valida que el valor de un elemento sea menor o igual que el contenido del atributo 'data-validation-max'.
 * Para que el elemento sea validado debe tener también el atributo: ( 'data-validation' ) con su valor respectivo
 * ('integer'; 'float'; 'date'; 'time').
 * @param obj (object) Elemento que contiene el valor a ser validado.
 * @return (boolean) Devuelve FALSE si no cumple con la condición, de lo contrario devuelve TRUE.*/
 function valLessThan(obj)
 {
     if ( obj.getAttribute( "data-validation" ) == "integer"
     || obj.getAttribute( "data-validation" ) == "float"
     || obj.getAttribute( "data-validation" ) == "float_3d" )
         return ( ( obj.value.replace(/\./g, '').replace(',', '.') * 1 ) <= ( obj.getAttribute( "data-validation-max" ) * 1 ) );
     else if ( obj.getAttribute( "data-validation" ) == "date" )
         return ( ( obj.value.replace(/\-/g, '') * 1 ) <= ( obj.getAttribute( "data-validation-max" ).replace(/\-/g, '') * 1 ) );
     else if ( obj.getAttribute( "data-validation" ) == "time" )
         return ( ( chkHour00To24( timeNormalToMilitar(obj.value) ).replace(/\:/g, '') * 1 )
             <= ( chkHour00To24( timeNormalToMilitar( obj.getAttribute( "data-validation-max" ) ) ).replace(/\:/g, '') * 1 ) );
 }

 /** Valida que el valor de un elemento sea mayor o igual que y menor o igual que
 * el contenido del atributo 'data-validation-min-max'. Ejemplo: 50-100 (mayor o igual a 50 y menor o igual a 100).
 * Para que el elemento sea validado debe tener también el atributo: ('data-validation') con su valor respectivo
 * ('integer'; 'float'; 'date'; 'time').
 * @param obj (object) Elemento que contiene el valor a ser validado.
 * @return (boolean) Devuelve FALSE si no cumple con la condición, de lo contrario devuelve TRUE.*/
 function valMoreAndLessThan(obj)
 {
     var arr = obj.getAttribute( "data-validation-min-max" ).split(obj.getAttribute( "data-validation" ) == "date" ? '/' : '-' );
     if ( obj.getAttribute( "data-validation" ) == "integer"
     || obj.getAttribute( "data-validation" ) == "float"
     || obj.getAttribute( "data-validation" ) == "float_3d" )
         return ( ( obj.value.replace(/\./g, '').replace(',', '.') * 1 )
         >= ( arr[0] * 1 )
         && ( obj.value.replace(/\./g, '').replace(',', '.') * 1 )
         <= ( arr[1] * 1 ) );
     else if ( obj.getAttribute( "data-validation" ) == "date" )
         return ( ( obj.value.replace(/\-/g, '') * 1 )
         >= ( arr[0].replace(/\-/g, '') * 1 )
         && ( obj.value.replace(/\-/g, '') * 1 )
         <= ( arr[1].replace(/\-/g, '') * 1 ) );
     else if ( obj.getAttribute( "data-validation" ) == "time" )
         return ( ( chkHour00To24( timeNormalToMilitar(obj.value) ).replace(/\:/g, '') * 1 )
         >= ( chkHour00To24( timeNormalToMilitar( arr[0] ) ).replace(/\:/g, '') * 1 )
         && ( chkHour00To24( timeNormalToMilitar( obj.value) ).replace(/\:/g, '') * 1 )
         <= ( chkHour00To24( timeNormalToMilitar( arr[1] ) ).replace(/\:/g, '') * 1 ) );
 }

 /** Valida los datos contenidos en un elemento HTML tipo array. Dicho elemento debe ser: INPUT tipo RADIO o CHECKBOX.
 * Cada INPUT del arreglo debe llamarse igual y para que cada elemento sea validado debe tener el atributo respectivo
 * definidos en jQryValidateData(). Si el elemento no cumple con la validación,
 * la clase 'error' (css) es asignada al elemento. De lo contrario dicha clase es removida.
 * Esta función trabaja con otra función auxiliar llamada: valObjsRadioCheck();
 * @param strName (string) El nombre de los elementos en forma de arreglo que serán validados.*/
 function valObjs(strName)
 {
     var objElementsByName = document.getElementsByName(strName);
     valObjsRadioCheck(objElementsByName);
 }

 /** Valida los datos contenidos en un arreglo de elementos HTML. Dichos elementos deben ser: INPUT tipo RADIO o CHECKBOX.
 * Por cada grupo de elementos con el mismo nombre es que hace la validación.
 * Para que cada elemento sea validado debe tener el atributo respectivo definidos en jQryValidateData().
 * Si el elemento no cumple con la validación, la clase 'error' (css) es asignada. De lo contrario, es removida.
 * @param arrayObj (array) Arreglo de elementos que contienen el valor a ser validado.
 * @return Devuelve NULL si el arreglo de elementos HTML no tienen definidos los atributos respectivos.*/
 function valObjsRadioCheck(arrayObj)
 {
     var nSelected = 0;
     if ( arrayObj[0].getAttribute( "data-validation" ) == "radio" || arrayObj[0].getAttribute( "data-validation" ) == "checkbox" ) {
         var dataValidation = arrayObj[0].getAttribute( "data-validation" );
         var strUn = ( arrayObj[0].getAttribute( "data-validation" ) == "checkbox" ) ? 'algún(os)' : 'un';
         var strS = ( arrayObj[0].getAttribute( "data-validation" ) == "checkbox") ? '(s)' : '';
     } else
         return null;
         for ( j = 0; j < arrayObj.length; j++ )
             if ( arrayObj[j].getAttribute( "data-validation" ) != dataValidation )
                 return null;
             else if ( arrayObj[j].checked )
                 nSelected = 1;
         ( nSelected == 0 ) ? displayErrorMsg( arrayObj[--j], 'Seleccione ' + strUn + ' Item' + strS ) : removeErrorMsg( arrayObj[--j] );
 }

 /** Muestra un mensaje debajo del elemento enviado como parámetro, con las características de la clase 'error'.
 * @param obj (object) Elemento al cual se le asignará el mensaje.
 * @param msj (string) Mensaje que será mostrado con las características de la clase 'error' (css).*/
 function displayErrorMsg(obj, msg)
 {
     if ( obj.parentNode.getElementsByTagName( "span" ).length == 0 ) {
         obj.setAttribute("class", "error" );
         var objDisplayErrorMsg = document.createElement( "span" );
         objDisplayErrorMsg.innerHTML = msg;
         objDisplayErrorMsg.setAttribute("class","help-block form-error");
         obj.parentNode.appendChild(objDisplayErrorMsg);
     } else {
         var oSpan = obj.parentNode.getElementsByTagName( "span" );
         oSpan[0].innerHTML = msg;
     }
 }

 /** Remueve un mensaje de error debajo del elemento enviado como parámetro y
 * elimina las características de la clase 'error' (css) de ese elemento.
 * @param obj (object) Elemento al cual se le removerá el mensaje y se eliminará la clase 'error' (css).*/
 function removeErrorMsg(obj)
 {
     var objP = obj.parentNode.getElementsByTagName( "span" );
     if ( objP.length == 1 )
         obj.parentNode.removeChild(obj.parentNode.lastChild);
     obj.setAttribute("class","valid");
 }

 /** Inicializa el valor de un elemento HTML de entrada de datos y le asigna la clase 'init' (css).
 * @param obj (object) Elemento que su valor será inicializado y que se le asignará la clase 'init' (css).
 * @param value (string) Valor con el que se inicializará el elemento.*/
 function initializeObj(obj, value)
 {
     if ( value != null )
         obj.value = value;
     var objP = obj.parentNode.getElementsByTagName( "span" );
     if ( objP.length == 1 )
         obj.parentNode.removeChild(obj.parentNode.lastChild);
     obj.setAttribute("class","init");
 }

 /** Muestra un mensaje debajo del elemento TABLE enviado como parámetro, con las características de la clase 'error'.
 * @param obj (object) Elemento TABLE al cual se le asignará el mensaje.
 * @param msj (string) Mensaje que será mostrado con las características de la clase 'error' (css).*/
 function displayErrorMsgTable(obj, msg)
 {
     if ( obj.parentNode.getElementsByTagName( "span" ).length == 0 ) {
         var objDisplayErrorMsg = document.createElement("span");
         objDisplayErrorMsg.innerHTML = msg;
         objDisplayErrorMsg.setAttribute("class","help-block form-error");
         obj.parentNode.appendChild(objDisplayErrorMsg);
     }
 }

 /** Remueve un mensaje de error debajo del elemento TABLE enviado como parámetro y
 * elimina las características de la clase 'error' (css) de ese elemento.
 * @param obj (object) Elemento TABLE al cual se le removerá el mensaje y se eliminará la clase 'error' (css).*/
 function removeErrorMsgTable(obj)
 {
     var objP = obj.parentNode.getElementsByTagName( "span" );
     if ( objP.length == 1 )
         obj.parentNode.removeChild(obj.parentNode.lastChild);
 }

 /** Valida que una cadena de carácteres cumpla con el debido formato de un correo eléctronico.
 * @param strValue (string) Cadena de carácteres a ser validada.
 * @return boolean Devuelve TRUE si cumple con el debido formato de un correo eléctronico.
 * De lo contrario devuelve FALSE.*/
 function valEmail(strValue)
 {
     var emailFilter=/^[^@\s]+@[^@\.\s]+(\.[^@\.\s]+)+$/;
     return emailFilter.test(strValue);
 }

 /** Valida que una cadena de carácteres cumpla con el debido formato de una dirección URL.
 * @param strValue (string) Cadena de carácteres a ser validada.
 * @return boolean Devuelve TRUE si cumple con el debido formato de una dirección URL.
 * De lo contrario devuelve FALSE.*/
 function valURL(strValue)
 {
     var urlFilter = /^(https?|ftp):\/\/((((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])(\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])(\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/(((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|\[|\]|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#(((\w|-|\.|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i; 
     return urlFilter.test(strValue);
 }

 /** Valida que el valor de un elemento sea una cadena de carácteres
 * que cumpla con el debido formato de un dato tipo Fecha (YYYY-MM-DD).
 * @param obj (object) Elemento con el valor a ser validado.
 * @return boolean Devuelve TRUE si cumple con el debido formato de un dato tipo Fecha (YYYY-MM-DD).
 * De lo contrario devuelve FALSE.*/
 function valDate(obj)
 {
     var dateFilter1 = /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/;
     var dateFilter2 = /^([0-9]{2})\/([0-9]{2})\/([0-9]{4})$/;
     return ( dateFilter1.test(obj.value) || dateFilter2.test(obj.value) );
 }

 /** Valida que una cadena de carácteres cumpla con el debido formato de un dato tipo Hora (HH:MM:XX).
 * @param str (string) Cadena de carácteres a ser validada.
 * @return boolean Devuelve TRUE si cumple con el debido formato de un dato tipo Hora (HH:MM:XX).
 * De lo contrario devuelve FALSE.*/
 function valTime(str)
 {
     var hora = str.value
     if (hora.length != 8)
         return false;
     var a = hora.charAt(0) //<=2
     var b = hora.charAt(1) //<4
     var c = hora.charAt(2) //:
     var d = hora.charAt(3) //<=5
     var e = hora.charAt(5) //:
     var f = hora.charAt(6) //<=5
     if ((a == 2 && b > 3) || (a > 2))//El valor que introdujo en la Hora no corresponde, introduzca un digito entre 00 y 23
         return false;
     if (d > 5) //El valor que introdujo en los minutos no corresponde, introduzca un digito entre 00 y 59
         return false;
     if (f > 5) //El valor que introdujo en los segundos no corresponde
         return false;
     if (c != ':' || e != ':') //Introduzca el caracter ':' para separar la hora, los minutos y los segundos
         return false;
     return true;
 }

 /** Valida que un elemento TABLE, tenga como mínimo el número de filas (elemento TR) definido en el parámetro minRow.
 * @param obj (object) Elemento TABLE. Tabla a ser validada.
 * @param minRow (integer) Representa el número mínimo de filas que debe tener la tabla.
 * @return boolean Devuelve FALSE si el número de filas de la tabla es menor a minRow. De lo contrario, devuelve TRUE.*/
 function valTable(obj, minRow)
 {
     return (obj.tBodies[0].rows.length < parseInt(minRow))?false:true;
 }

 /** Inicializa los valores de los elementos HTML de entrada de datos (INPUT, SELECT y TEXTAREA),
 *  contenidos dentro el elemento pasado como parametro (FORM, DIV, TABLE...).
 * Para que el valor del elemento sea inicializado debe tener el atributo respectivo 'data-validation'.
 * Esta función implementa initObj() como auxiliar.
 * Ver también: {@link constraintsData}, {@link formatData}.
 * @param obj (object) Elemento que su valor será inicializado.*/
 function initObjs(obj)
 {
     var objsInput = obj.getElementsByTagName( "input" );
     var objsRadioCheck = [];
     var k = 0;
     for ( var i = 0; i < objsInput.length; i++ )
         if ( objsInput[i].getAttribute("type") != "button" 
         && objsInput[i].getAttribute("type") != "submit"
         && objsInput[i].getAttribute("type") != "radio"
         && objsInput[i].getAttribute("type") != "checkbox"
         && objsInput[i].getAttribute( "data-validation" ) != null)
             initObj( objsInput[i] );
         else if ( objsInput[i].getAttribute( "type" ) == "radio" || objsInput[i].getAttribute( "type" ) == "checkbox" )
             objsRadioCheck[k++] = objsInput[i];
     if ( objsRadioCheck.length > 0 ) {
         var key = 0;
         var keyAux = 0;
         var strRadioCheckName = objsRadioCheck[0].name;
         var mObjsRadioCheck = [];
       	 mObjsRadioCheck[key] = [];
         mObjsRadioCheck[key][keyAux++] = objsRadioCheck[0];
         for ( var i = 1; i < objsRadioCheck.length; i++ )
             if ( strRadioCheckName == objsRadioCheck[i].name ) {
                 while ( strRadioCheckName == objsRadioCheck[i].name ) {
                     mObjsRadioCheck[key][keyAux++] = objsRadioCheck[i++];
                     if ( i == objsRadioCheck.length)
                         break;
                 }
                 if ( i == objsRadioCheck.length )
                     break;
                 else {
                     strRadioCheckName = objsRadioCheck[i--].name;
                     keyAux = 0;
                     mObjsRadioCheck[++key] = [];
                 }
             }
         for ( var i = 0; i < mObjsRadioCheck.length; i++ )
             intObjsRadioCheck( mObjsRadioCheck[i] );
     }
     var objsSelect = obj.getElementsByTagName( "select" );
     for ( var i = 0; i < objsSelect.length; i++ )
         initObj( objsSelect[i] );
     var objsTextArea = obj.getElementsByTagName( "textarea" );
     for ( var i = 0; i < objsTextArea.length; i++ )
         initObj( objsTextArea[i] );
 }

 /** Inicializa el valor de un elemento HTML de entrada de datos.
 * Para que el valor del elemento sea inicializado debe tener el atributo respectivo 'data-validation'.
 * Esta función implementa initializeObj() como auxiliar.
 * @param obj (object) Elemento que su valor será inicializado.*/
 function initObj(obj){
     if ( (obj.getAttribute( "data-validation" )== "required" ) 
     || (obj.getAttribute( "data-validation" )=="length")
     || (obj.getAttribute( "data-validation" )=="email")
     || (obj.getAttribute( "data-validation" )=="url")
     || (obj.getAttribute( "data-validation" )=="textarea") )
         initializeObj( obj, '' );
     else if ( obj.getAttribute( "data-validation" ) == "integer" )
         initializeObj( obj, '0' );
     else if ( obj.getAttribute( "data-validation" ) == "float" )
         initializeObj( obj, '0,00' );
     else if ( obj.getAttribute( "data-validation" ) == "float_3d" )
         initializeObj( obj, '0,000' );
     else if ( ( obj.getAttribute( "data-validation" ) == "select" ) || ( obj.getAttribute( "data-validation" ) == "select-small" ) )
         initializeObj( obj, 'null' );
     else if ( obj.getAttribute( "data-validation" ) == "time" )
         initializeObj( obj, currentTime() );
     else if ( obj.getAttribute( "data-validation" ) == "date" )
         initializeObj( obj, dateOfToday( 'YYYYMMDD', '-' ) );
     //*else if (obj.getAttribute( "data-validation" ) == 'table' ) */
 }

 /** Inicializa los valore de un arreglo de elementos HTML de entrada de datos tipo RADIO o CHECKBOX.
 * Para que los valores del arreglo de elementos sean inicializado deben tener el atributo 'data-validation'...
 * 'radio' o 'checkbox' respectivamente.
 * Esta función implementa initializeObj() como auxiliar.
 * @param arrayObj (array) Arreglo de elementos HTML de entrada de datos tipo RADIO o CHECKBOX
 * para que sus valores sean inicializado.*/
 function intObjsRadioCheck(arrayObj)
 {
     if ( arrayObj[0].getAttribute( "data-validation" ) == "radio" || arrayObj[0].getAttribute( "data-validation" ) == "checkbox") {
         for ( var j = 0; j < arrayObj.length; j++ )
             arrayObj[j].checked = false;
         initializeObj(arrayObj[--j]);
     }
 }

 /** Inicializar Objeto de Selección Múltiple.
 * Descripción: Inicializar Objeto de Selección Múltiple (Combo).
 * Nota: Esta método hace referencia a la función 'move()', la cual está ubicada en el archivo 'combo.js'.
 * @param objSelect (object) Elemento tipo Combo (múltiple) de donde seleccionan los Items.
 * @param objSelected (object) Elemento tipo Combo (múltiple) donde se envian los Items seleccionados.*/
 function initObjsSelectMultiple(objSelect, objSelected) {
     for ( var i = 0; i < objSelected.length; i++ )
         objSelected[i].selected = true;
     move( 'left', objSelect, objSelected );
     initializeObj( objSelected, 'null' );
 }


El siguiente archivo posee 3 funciones para formatear la entrada de números enteros y flotantes (a 2 y 3 decimales, respectivamente) en el elemento <input> correspondiente.

  • formato_float_3d()
  • formato_float()
  • formato_numeric()
Son invocado desde el archivo validateData.js en la función formatData(), precisamente para darle formato a las entradas que sean así requeridas.

numero.js

 /** Coloca formato de número real (separadores de miles y decimales de tres (3) dígitos)
 * a un elemento INPUT automáticamente, mientras el usuario presiona las teclas.
 * Nota: El teclado solo aceptará números y el punto decimal.
 * Ver también: {@link formato_float} y {@link formato_numeric}.
 * @param fld object Elemento INPUT que tendrá el valor tecleado.
 * @param milSep string Separador de miles, puede ser punto ó coma.
 * @param decSep string Separador de decimales, puede ser punto ó coma.
 * @param e object Evento de presionar una tecla.
 * @return Retorna FALSE si no se puede colocar el formáto; de lo contrario, coloca el formato.*/
 function formato_float_3d(fld, milSep, decSep, e)
 {
     var tipo = e.keyCode;
     if ( tipo == 8 ) {  // 3 8,37,39,46
         return true;
     }
     var sep = 0;
     var key = '';
     var i = j = 0;
     var len = len2 = 0;
     var strCheck = '0123456789';
     var aux = aux2 = '';
     var whichCode = (window.Event) ? e.which : e.keyCode;
     //if (whichCode == 13) return true; // Enter
     key = String.fromCharCode(whichCode); // Get key value from key code
     if ( strCheck.indexOf(key) == -1 )
         return false; // Not a valid key
     len = fld.value.length;
     for ( i = 0; i < len; i++ )
         if ( ( fld.value.charAt(i) != '0' ) && ( fld.value.charAt(i) != decSep ) )
             break;
     aux = '';
     for ( ; i < len; i++ )
         if ( strCheck.indexOf( fld.value.charAt(i) ) != -1 )
             aux += fld.value.charAt(i);
     aux += key;
     len = aux.length;
     if ( len == 0 )
         fld.value = '';
     if ( len == 1 )
         fld.value = '0'+ decSep + '00' + aux;
     if ( len == 2 )
         fld.value = '0'+ decSep + '0' + aux;
     if ( len == 3 )
         fld.value = '0'+ decSep + aux;
     if ( len > 3 ) {
         aux2 = '';
         for ( j = 0, i = len - 4; i >= 0; i-- ) {
             if ( j == 3 ) {
                 aux2 += milSep;
                 j = 0;
             }
             aux2 += aux.charAt(i);
             j++;
         }
         fld.value = '';
         len2 = aux2.length;
         for ( i = len2 - 1; i >= 0; i-- )
             fld.value += aux2.charAt(i);
         fld.value += decSep + aux.substr(len - 3, len);
     }
     return false;
 }

 /** Coloca formato de número real (separadores de miles y decimales) a un elemento INPUT automáticamente,
 * mientras el usuario presiona las teclas. Nota: El teclado solo aceptará números y el punto decimal.
 * Ver también: {@link formato_float_3d} y {@link formato_numeric}.
 * @param fld object Elemento INPUT que tendrá el valor tecleado.
 * @param milSep string Separador de miles, puede ser punto ó coma.
 * @param decSep string Separador de decimales, puede ser punto ó coma.
 * @param e object Evento de presionar una tecla.
 * @return Retorna FALSE si no se puede colocar el formáto; de lo contrario, coloca el formato.*/
 function formato_float(fld, milSep, decSep, e)
 {
     var tipo=e.keyCode;
     if ( tipo == 8 ) { // 3 8,37,39,46
         return true;
     }
     var sep = 0;
     var key = '';
     var i = j = 0;
     var len = len2 = 0;
     var strCheck = '0123456789';
     var aux = aux2 = '';
     var whichCode = (window.Event) ? e.which : e.keyCode;
     //if (whichCode == 13) return true; // Enter
     key = String.fromCharCode(whichCode); // Get key value from key code
     if ( strCheck.indexOf(key) == -1 )
         return false; // Not a valid key
     len = fld.value.length;
     for ( i = 0; i < len; i++ )
         if ( ( fld.value.charAt(i) != '0' ) && ( fld.value.charAt(i) != decSep ) )
             break;
     aux = '';
     for ( ; i < len; i++ )
         if ( strCheck.indexOf( fld.value.charAt(i) ) != -1 )
             aux += fld.value.charAt(i);
     aux += key;
     len = aux.length;
     if ( len == 0 )
         fld.value = '';
     if ( len == 1 )
         fld.value = '0'+ decSep + '0' + aux;
     if ( len == 2 )
         fld.value = '0'+ decSep + aux;
     if ( len > 2 ) {
         aux2 = '';
         for ( j = 0, i = len - 3; i >= 0; i-- ) {
             if ( j == 3 ) {
                 aux2 += milSep;
                 j = 0;
             }
             aux2 += aux.charAt(i);
             j++;
         }
         fld.value = '';
         len2 = aux2.length;
         for ( i = len2 - 1; i >= 0; i-- )
             fld.value += aux2.charAt(i);
         fld.value += decSep + aux.substr(len - 2, len);
     }
     return false;
 }

 /** Coloca formato de número entero (separadores de miles) a un elemento INPUT automáticamente,
 * mientras el usuario presiona las teclas. Nota: El teclado solo aceptará números y el punto decimal.
 * Ver también: {@link formato_float} y {@link formato_float_3d}.
 * @param fld object Elemento INPUT que tendrá el valor tecleado.
 * @param milSep string Separador de miles, puede ser punto ó coma.
 * @param decSep string Separador de decimales, puede ser punto ó coma.
 * @param e object Evento de presionar una tecla.
 * @return Retorna FALSE si no se puede colocar el formáto; de lo contrario, coloca el formato.*/
 function formato_numeric(fld, milSep, decSep, e)
 {
     var tipo=e.keyCode;
     if ( tipo == 8 )  // 3 8,37,39,46
         return true;
     var key = '';
     var i = j = 0;
     var len = len2 = 0;
     var strCheck = '0123456789';
     var aux = aux2 = '';
     var whichCode = (window.Event) ? e.which : e.keyCode;
     //if (whichCode == 13) return true; // Enter
     key = String.fromCharCode(whichCode); // Get key value from key code
     if ( strCheck.indexOf(key) == -1 )
         return false; // Not a valid key
     len = fld.value.length;
     for ( i = 0; i < len; i++ )
         if ( ( fld.value.charAt(i) != '0' ) )
             break;
         aux = '';
         for ( ; i < len; i++ )
             if ( strCheck.indexOf( fld.value.charAt(i) ) != -1 )
                 aux += fld.value.charAt(i);
         aux += key;
         len = aux.length;
         aux2 = '';
         for ( j = 0, i = len - 1; i >= 0; i-- ) {
             if ( j == 3 ) {
                 aux2 += milSep;
                 j = 0;
             }
             aux2 += aux.charAt(i);
             j++;
         }
         fld.value = '';
         len2 = aux2.length;
         for ( i = len2 - 1; i >= 0; i-- )
             fld.value += aux2.charAt(i);
         fld.value += aux.substr(len - 0, len);
         return false;
 }


En el siguiente archivo, hay una función que devuelve la fecha del día (con formato a convenir). Esta función la utilizamos en el ejemplo, para inicializar las entradas tipo fecha ( date ).

date.js

 function dateOfToday(format, separator)
 {
     var f = new Date();
     separator = separator == null ? '' : separator;
     switch ( format.toUpperCase() ) {
         case 'YYYYMMDD':
             return f.getFullYear() + separator + pad( ( f.getMonth() + 1 ) , 2 ) + separator + pad( f.getDate(), 2 );
             break;
         case 'YYMMDD':
             return f.getFullYear().toString().substr(2,2) + separator + pad( ( f.getMonth() + 1 ) , 2 ) + separator + pad( f.getDate(), 2 );
             break;
         case 'DDMMYYYY':
             return  pad( f.getDate(), 2 ) + separator + pad( ( f.getMonth() + 1 ) , 2 ) + separator + f.getFullYear();
             break;
         case 'DDMMYY':
             return  pad( f.getDate(), 2 ) + separator + pad( ( f.getMonth() + 1 ) , 2 ) + separator + f.getFullYear().toString().substr( 2, 2 ); 
             break;
         default:
             return f;
     }
 }


El siguiente archivo tiene la función currentTime(), la cual devuelve la hora actual. La utilizamos en el ejemplo, para inicializar las entradas tipo hora ( time ).

Y otra función de conversión (a hora militar), que nos sirve para procesar comparaciones matemáticas. Es invocado desde el archivo validateData.js en las funciones valMoreThan() y valMoreAndLessThan().

time.js

 /** Convierte una hora normal a hora militar.
 * Ej: '03:45:PM' => '15:45:00'
 * @param hora (string) Cadena de caracteres representando la hora con formato normal.
 * @return hora (string) Cadena de caracteres representando la hora con formato militar.*/
 function timeNormalToMilitar(hora)
 {
     var meridian = hora.substr(6, 1);
     hora = hora.replace('AM', '00');
     hora = hora.replace('PM', '00');
     if ( meridian == 'P' ) {
         var arr = hora.split(':');
         arr[0] = parseInt( arr[0] ) + 12;
         if ( arr[0] == 24 )
             arr[0] = '00';
         hora = pad( arr[0], 2 ) + ':' + pad( arr[1], 2 ) + ':' + arr[2];
     }
     return hora;
 }

 /** Formatea una cadena de caracteres con una cantidad de ceros (0)
 * a la izquierda, según lo especifique el parámetro 'size'.
 * @param num (string) Cadena de caracteres que será formateada; generalmente pueden ser números.
 * @param size (integer) Cantidad de ceros (0) que se colocaran a la izquierda.
 * @return (string) Cadena de caracteres formateada con una cantidad de ceros (0) especificada.*/
 function pad(num, size)
 {
     var s = "000000000000000000" + num;
     return s.substr(s.length-size);
 }

 /** Chequea que si la hora es 00 la convierta a 24,
 * esta acción se aplica para operaciones matemáticas.
 * @param val (string) Cadena de caracteres con formato de hora.
 * @return (string) Cadena de caracteres con formato de hora,
 * si la hora es 00 la convierta a 24.*/
 function chkHour00To24(val)
 {
     var arr = val.split(':');
     if ( arr[0] == '00' )
         arr[0] = 24;
     return arr[0] + ':' + arr[1] + ':' + arr[2];
 }

 /** Hora actual.
 * Hora del momento actual.
 * @return string Devuelve la hora del momento.*/
 function currentTime()
 {
     var dig = new Date();
     var h = dig.getHours();
     var m = dig.getMinutes(); //var s = dig.getSeconds();
     var ap = "AM";
     if ( h > 12 ) {
         ap = "PM";
         h = h - 12;
     }
     if ( h == 0 )
         h = 12;
     if ( h < 9 )
         h = "0" + h;
     if ( m <= 9 )
         m = "0" + m;
     //if ( s <= 9 ) s = "0" + s;
     return h + ':' + m + ':' + ap;
 }


El siguiente archivo contiene funciones que manipulan el contenido ( <option> ) de los elementos <select> "multiple". Estas funciones son específicas para la operatividad de lo tipos de elementos con dicha característica.

combo.js

 /** Funciones reutilizables para objetos combo */

 function move(side, docFormObjLista, docFormObjSelected)
 {
     this.bubbleSort = function (inputArray, inputArray1, start, rest)
     {
         for ( var i = rest - 1; i >= start;  i-- ) {
             for ( var j = start; j <= i; j++ ) {
                 if ( inputArray1[j+1] < inputArray1[j] ) {
                     var tempValue = inputArray[j];
                     var tempValue1 = inputArray1[j];
                     inputArray[j] = inputArray[j+1];
                     inputArray1[j] = inputArray1[j+1];
                     inputArray[j+1] = tempValue;
                     inputArray1[j+1] = tempValue1;
                 }
             }
         }
         return inputArray;
     }
     this.ClearList = function (OptionList, TitleName) { OptionList.length = 0; }
     var temp1 = [];
     var temp2 = [];
     var tempa = [];
     var tempb = [];
     var current1 = 0;
     var current2 = 0;
     var y = 0;
     var attribute;
     //assign what select attribute treat as attribute1 and attribute2
     if (side == "right") {  
         attribute1 = docFormObjLista;
         attribute2 = docFormObjSelected;
     } else {
         attribute1 = docFormObjSelected;
         attribute2 = docFormObjLista;
     }
     //fill an array with old values seleccionados
     for ( var i = 0; i < attribute2.length; i++ ) {
         y = current1++;
         temp1[y] = attribute2.options[i].value;
         tempa[y] = attribute2.options[i].text;
     }
     //assign new values to arrays
     for ( var i = 0; i < attribute1.length; i++ ) {
         if ( attribute1.options[i].selected ) {
             //llena un vector con los valores todos seleccionados
             y=current1++;
             temp1[y] = attribute1.options[i].value;
             tempa[y] = attribute1.options[i].text;
         } else {
             //llena un vector con los valores no seleccionados
             y=current2++;
             temp2[y] = attribute1.options[i].value;
             tempb[y] = attribute1.options[i].text;
         }
     }
     //sort atribute2
     temp1 = bubbleSort( temp1, tempa, 0, temp1.length - 1 );
     //sort atribute1
     temp2 = bubbleSort( temp2, tempb, 0, temp1.length - 1 );
     //generating new options
     ClearList( attribute2, attribute2 );
     for ( var i = 0; i < temp1.length; i++ ) {
         attribute2.options[i] = new Option();
         attribute2.options[i].value = temp1[i];
         attribute2.options[i].text =  tempa[i];
     }
     //generating new options
     ClearList(attribute1,attribute1);
     if (temp2.length > 0) {
         for ( var i = 0; i < temp2.length; i++ ) {
             attribute1.options[i] = new Option();
             attribute1.options[i].value = temp2[i];
             attribute1.options[i].text =  tempb[i];
         }
     }
     return true;
 }

 function getValues(objForm, objStrArray){
     if (objForm.length!=0)
         for (i=0;i < objForm.length;i++)
             objStrArray.value = ( i == 0 ) ? objForm.options[i].value : objStrArray.value + ", " + objForm.options[i].value; 
     else
         objStrArray.value = '';
     return objStrArray.value;
 }


Y por último tenemos, el archivo que determina el estilo que tendrá cada elemento, según su validación respectiva.

validateData.css

 .help-block {
     display: inline;
     padding-left: 6px;
     font-size: 85%;
 }

 span.form-error.help-block {
     display: block;
     color: red;
     margin-top: 0px;
     margin-bottom: 0px;
     padding-left: 0;
 }

 div.form-error {
     padding: 6px 12px;
     line-height: 180%;
     background: #ffe5ed;
     border-radius: 4px;
     margin-bottom: 22px;
     color: darkred;
 }

 input {
     width:99%;
     border: #CCC solid 1px;
     border-radius: 3px;
     padding: 3px;
 }

 input:hover {
     border: dotted 2px; #000 !important;
 }

 input.init {
     background: #FAFAFA; /*url(../img/icon-ok.png) no-repeat right center #E3FFE5*/
     color: #424242;
     border-color: #BFBFBF !important;
 }

 input.valid {
     background: #F8FEF7; /*url(../img/icon-ok.png) no-repeat right center #E3FFE5*/
     color: #002f00;
     border-color: #96B796 !important;
 }

 input.valid:hover {
     border: dotted 2px; #000 !important;
 }

 input.error {
     background: #FFFAFA; /*url(../img/icon-fail.png) no-repeat right center #ffebef*/
     color: #480000;
     border-color: red !important;
 }

 input.error:hover {
     border: dotted 2px; #000 !important;
 }

 input[type="radio"] {
     width:10%;
 }

 input[type="checkbox"] {
     width:10%;
 }

 select {
     border: #CCC solid 1px;
     border-radius: 3px;
     padding: 3px;
 }

 select.init {
     background: #FAFAFA; /*url(../img/icon-ok.png) no-repeat right center #E3FFE5*/
     color: #424242;
     border-color: #BFBFBF !important;
 }

 select[data-validation="select"] {
    width:99%;
 }

 select:hover {
     border: dotted 2px; #000 !important;
 }

 select.valid {
     background: #F8FEF7;
     color: #002f00;
     border: 1px solid;
     border-color: #96B796 !important;
     padding: 3px;
     font-size: 14px;
    /* height:24px;*/
 }

 select.valid:hover {
     border: dotted 2px; #000 !important;
 }

 select.error {
     background: #FFFAFA;
     color: #480000;
     border: 1px solid;
     border-color: red !important;
     padding: 3px;
     font-size: 14px;
     /* height:24px;*/
 }

 select.error:hover {
     border: dotted 2px; #000 !important;
 }

 textarea {
     width:99%;
     border: #CCC solid 1px;
     border-radius: 3px;
     padding: 3px;
 }

 textarea:hover {
     border: dotted 2px; #000 !important;
 }

 textarea.valid {
     background: #F8FEF7; /*url(../img/icon-ok.png) no-repeat right top*/
     color: #002f00;
     border-color: #96B796 !important;
 }

 textarea.valid:hover {
     border: dotted 2px; #000 !important;
 }

 textarea.error {
     background: #FFFAFA; /*url(../img/icon-fail.png) no-repeat right top*/
     color: #480000;
     border-color: red !important;
 }

 textarea.error:hover {
     border: dotted 2px; #000 !important;
 }


He aquí el ejemplo:


Tool developed at revolution, under free software. Copyleft 2017.