Ir directamente al contenido de esta página
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:
label
(inglés) y por medio de title
(inglés).label
e incluso title
, como de hecho Freedom Scientific recomienda en un boletín del 13 de octube de 2003, Tips on HTML code and expected behavior from JAWS (inglés)— así como convenciones bastante asentadas que pueden añaden información adicional. Por ejemplo, hemos aprendido que el formulario de la esquina superior derecha de una página suele ser el buscador.No parece, pues, que este punto siga siendo aplicable.
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.
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:
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: