Ir directamente al contenido de esta página

codexexempla.org

La usabilidad está en los detalles: limpiar campos de formulario con JavaScript

Tabla de contenidos

  1. Accesibilidad y el texto inicial de un campo de formulario
  2. Problemas derivados y una solución común: limpiar los campos
  3. El problema de esta solución común
  4. Pruebas en navegadores

Accesibilidad y el texto inicial de un campo de formulario

El punto 10.4 de las WCAG 1.0 (inglés) dice:

Until user agents handle empty controls correctly, include default, place-holding characters in edit boxes and text areas. [Priority 3]

[Hasta que los agentes de usuario manejen correctamente controles vacíos, incluya caracteres por defecto en las cajas o áreas de texto editables. (Prioridad 3)]

El objetivo es facilitar que los lectores navegadores antiguos —muy, muy antiguos— sean capaces de seleccionar el campo del formulario, y por otro lado ofrecer información sobre el propósito de éste para los usuarios, especialmente para los que emplean un lector de pantalla. Mi humilde punto de vista es que no son necesarios:

No parece, pues, que este punto siga siendo aplicable.

Problemas derivados y una solución común: limpiar los campos

Sin embargo, muchos desarrolladores web sentimos el vehemente deseo de cumplir el mayor número de puntos posibles de las pautas del W3C, y nos sentimos orgullosos cuando podemos añadir a la lista los que corresponden a la prioridad 3. Además, en este caso, no parece demasiado oneroso añadir un simple texto al atributo value de un input o al contenido de un textarea.

No obstante, aplicar este punto supone una serie de problemas a nivel de usabilidad, relacionados con el hecho de que el usuario debe limpiar el campo antes de rellenarlo con los datos pertinentes:

Para prevenir estos problemas, y evitar la programación en el lado del servidor de un script de validación que limpiase las coincidencias con esa cadena —o de subcadenas, lo que aumentaría su complejidad, si es que no lo hace virtualmente imposible si pensamos que una cadena puede ser un caracter aislado—, se suele complementar el texto con un script del lado del cliente que limpie los campos una vez que se han seleccionado. Un ejemplo podría ser éste:


 01  function asignar_evento (x,y,z) {
 02     if (x.addEventListener) { x.addEventListener(y,z,false); } else { x.attachEvent('on'+y,z); }
 03  }
 04  
 05  function asignar_escuchas_cajas(){
 06      var inputs = document.getElementsByTagName('input');
 07      var textareas = document.getElementsByTagName('textarea');
 08      for (var h=0;h<inputs.length;h++){
 09          if(inputs[h].type=='text'){ asignar_evento(inputs[h],'focus',limpiar); }
 10      }
 11      for (var i=0;i<textareas.length;i++){
 12          asignar_evento(textareas[i],'focus',limpiar);
 13      }
 14  }
 15  
 16  function limpiar(evento){
 17      if(document.addEventListener){ var caja_a_limpiar = this; } else { var caja_a_limpiar = evento.srcElement; }
 18      caja_a_limpiar.value = '';
 19  }
 20  
 21  asignar_evento(window,'load',asignar_escuchas_cajas);
            

Lo que este código hace es asignar una escucha del evento onfocus sobre cada input de tipo texto y sobre cada textarea presente en una página, y cuando el campo en concreto recibe el foco lanza una función que establece su valor a una cadena vacía.

Parece correcto, ¿no? Bueno, siga leyendo.

El problema de esta solución común

Lo que me interesa en este caso no es explicar cómo funciona el script, sino llamar la atención sobre el hecho de que el programador web tiene que desarrollar la capacidad de ver posibles problemas donde en principio todo funciona bien. Hagamos la prueba: he creado un ejemplo con el código de arriba; ruego al lector que lo compruebe y detecte el problema que plantea.

¿Ya? Bien. ¿Cuál es el problema? Una pista: el problema no está en que el script no funcione correctamente, sino en que funciona correctamente continuamente. Lo que hay que hacer es imaginar un uso real, y suponer un caso hipotético como éste:

  1. Encuentro un formulario para enviar un comentario al autor de un artículo que me ha interesado muchísimo.
  2. Relleno los datos del formulario, alegrándome porque esos textos al estilo de «escriba aquí su mensaje» desaparecen inmediatamente en cuanto hago clic sobre el campo en cuestión.
  3. En el momento en el que voy a pulsar el botón de enviar, me doy cuenta de que he cometido una errata en mi dirección de correo o, peor aún, en el cuerpo del mensaje.
  4. Decido rectificar el error y vuelvo a hacer clic sobre el campo de mi correo electrónico o, peor aún, en el campo del mensaje.
  5. Mi dirección de correo desaparece, por lo que tengo que volver a introducirla completa, en lugar de corregir la errata. O mi mensaje de quinientos caracteres redactado de forma cuidadosa por respeto al autor que ha de leerlo desaparece.

Así, pues, si se desea incluir un JavaScript como éste, hay que tener en cuenta una situación como la que he descrito, y ampliar el código:


 01  var cajas_ya_activadas = new Array();
 02  
 03  function asignar_evento (x,y,z) {
 04      if (x.addEventListener) { x.addEventListener(y,z,false); } else { x.attachEvent('on'+y,z); } 
 05  }
 06  
 07  function asignar_escuchas_cajas(){
 08      var inputs = document.getElementsByTagName('input');
 09      var textareas = document.getElementsByTagName('textarea');
 10      for (var h=0;h<inputs.length;h++){
 11          if(inputs[h].type=='text'){ asignar_evento(inputs[h],'focus',limpiar); }
 12      }
 13      for (var i=0;i<textareas.length;i++){
 14          asignar_evento(textareas[i],'focus',limpiar);
 15      }
 16  }
 17  
 18  function limpiar(evento){
 19      if(document.addEventListener){ var caja_a_limpiar = this; } else { var caja_a_limpiar = evento.srcElement; }
 20      var nueva = 1;
 21      for(var j=0;j<cajas_ya_activadas.length;j++){
 22          if(caja_a_limpiar==cajas_ya_activadas[j]){ nueva = 0; }
 23      }
 24      if(nueva){
 25          caja_a_limpiar.value = '';
 26          cajas_ya_activadas[cajas_ya_activadas.length] = caja_a_limpiar;
 27      }
 28  }
 29  
 30  asignar_evento(window,'load',asignar_escuchas_cajas);
            

Lo que añado aquí es una matriz en la que recojo las referencias a los campos de texto que ya han sido limpiados con anterioridad (línea 01). Cuando se lanza la función limpiar, comparo el campo que la ha llamado con los valores almacenados hasta el momento en la matriz anterior (líneas 21 a 23), y dependiendo de eso el valor del booleano nueva es el que decide si se limpia la caja o no. Aquí el ejemplo completo.

Por si alguien desea emplearlo, aquí tiene un .zip con el archivo .js, aunque, como he dicho arriba, creo que soy más partidario de dejar el campo en blanco sin más.

He comprobado que este script funciona correctamente —sobre Windows— en:

Contacto

En virtud de la Ley Orgánica 15/1999 de Protección de Datos de Carácter Personal le informo de que los datos que proporcione no serán empleados para otro fin que el de responder a su mensaje. En especial, me comprometo a no cederlos a terceros ni a emplearlos para enviar información no solicitada.

Del blog de Digital Icon