Gestión de Eventos y Formularios en JavaScript.
Gestión de Eventos y Formularios en JavaScript.
Contenido
La mayor parte de interactividad entre una página web y el usuario tiene lugar a través de un
formulario. Es ahí donde nos vamos a encontrar con los campos de texto, botones, checkboxes,
listas, etc. en los que el usuario introducirá los datos, que luego se enviarán al servidor.
En este apartado verás cómo identificar un formulario y sus objetos, cómo modificarlos, cómo
examinar las entradas de usuario, enviar un formulario, validar datos, etc.
Los formularios y sus controles, son objetos del DOM que tienen propiedades únicas, que otros
objetos no poseen. Por ejemplo, un formulario tiene una propiedad action , que le indica al
navegador donde tiene que enviar las entradas del usuario, cuando se envía el formulario. Un control
select posee una propiedad llamada selectedIndex , que nos indica la opción de ese campo que ha
sido seleccionada por el usuario.
El objeto de JavaScript Form , es una propiedad del objeto document . Se corresponderá con la etiqueta
<FORM> del HTML. Un formulario podrá ser enviado llamando al método submit de JavaScript, o bien
haciendo click en el botón submit del formulario.
-1-
Diseño Web en Entorno Cliente DAW
Método 2
A través del método getElementsByTagName() del DOM, el cual nos permite acceder a un objeto a
través de la etiqueta HTML que queramos. Por ejemplo para acceder a los objetos con etiqueta form
haremos:
var formularios = document.getElementsByTagName("form");
var primerFormulario = formularios[0]; // primer formulario del documento
Otra posibilidad interesante que te permite el método anterior, es la de buscar objetos con un padre
determinado, por ejemplo:
var menu=document.getElementById("menulateral");
var formularios=menu.getElementsByTagName("form"); // formularios contenidos en el menu
lateral
var primerFormulario= formularios[0]; // primer formulario en el menú lateral
Método 3
Otro método puede ser a través de la colección forms[] del objeto document . Esta colección es un
array, que contiene la referencia a todos los formularios que tenemos en nuestro documento.
-2-
Gestión de eventos y formularios en JavaScript Tema 5
Por ejemplo:
var formularios = document.forms; // la referencia a todos los formularios del documento
var miformulario = formularios[0]; // primer formulario del documento
o bien:
var miformulario = document.forms[0]; // primer formulario del documento
o bien:
var miformulario = formularios["contactar"]; // referenciamos al formulario con name
"contactar"
Te mostraré con un ejemplo cómo sería el árbol de nivel 2 del DOM para un formulario típico:
-3-
Diseño Web en Entorno Cliente DAW
Los dos árboles que te mostré anteriormente pueden ser útiles para diferentes propósitos. El árbol
del DOM de nivel 2, se puede utilizar para leer y escribir en todo el documento con un nivel muy fino
de granuralidad (especificidad con la que se define un nivel de detalle). El árbol del DOM de nivel 0, hace muchísimo
más fácil leer y escribir los controles del formulario.
Tienes que darte cuenta que, aunque utilices las técnicas del DOM 0 o DOM 2, los objetos siguen
siendo los mismos. Por ejemplo:
var elFormulario = document.getElementById("miFormulario");
var control = elFormulario.busqueda;
"Son las palabras y las fórmulas, más que la razón, las que crean la mayoría de nuestras opiniones."
LE BON, Gustave
objetoFormulario.action = "http://www.educacion.gob.es/recepcion.php";
Propiedad form.elements[]
La propiedad elements[] de un formulario es una colección, que contiene todos los objetos input
dentro de un formulario. Esta propiedad es otro array, con todos los campos input en el orden en el
cual aparecen en el código fuente del documento.
-4-
Gestión de eventos y formularios en JavaScript Tema 5
Generalmente, es mucho más eficaz y rápido referenciar a un elemento individual usando su ID, pero
a veces, los scripts necesitan recorrer cada elemento del formulario, para comprobar que se han
introducido sus valores correctamente.
Por ejemplo, empleando la propiedad elements[] , podemos hacer un bucle que recorra un
formulario y si los campos son de tipo texto, pues que los ponga en blanco:
var miFormulario = document.getElementById("contactar");
// guardamos la referencia del formulario en una variable.
-5-
Diseño Web en Entorno Cliente DAW
Para poder trabajar con los objetos de un formulario, lo primero que necesitas saber es, cómo
referenciar a ese objeto. Eso puedes hacerlo directamente a través de su ID, o bien con su nombre de
etiqueta, empleando para ello los métodos del DOM nivel 2. O también se puede hacer usando la
sintaxis del DOM nivel 0, y construyendo la jerarquía que comienza por document , luego el formulario
y finalmente el control.
Lo mejor es identificar cada uno de los objetos con un atributo id que sea único, y que no se repita
en el documento, así para acceder a cualquier objeto dentro de nuestro documento o formulario lo
haremos con:
document.getElementById("id-del-control")
document.nombreFormulario.name-del-control
-6-
Gestión de eventos y formularios en JavaScript Tema 5
Para poder usar estos objetos dentro de nuestros scripts de JavaScript, simplemente será suficiente
con asignar un atributo id , a cada uno de los elementos. Te recomiendo que asignes a cada objeto de
tu formulario un atributo id único y que coincida con el name de ese objeto.
Cuando se envían los datos de un formulario a un programa en el lado del servidor, lo que en
realidad se envía son los atributos name , junto con los valores (contenido del atributo value ) de cada
elemento. Sin lugar a dudas, la propiedad más utilizada en un elemento de tipo texto es por lo tanto
value . Un script podrá recuperar y ajustar el contenido de la propiedad value en cualquier momento.
Por cierto, el contenido de un value es siempre una cadena de texto, y quizás puedas necesitar
realizar conversiones numéricas si quieres realizar operaciones matemáticas con esos textos.
En este tipo de objetos, los gestores de eventos (que verás más adelante) se podrán disparar (cuando
ese evento es ejecutado o es lanzado. Por lo tanto lo podemos traducir por ejecutar o lanzar) de múltiples formas: por
ejemplo, cuando pongamos el foco en un campo (situar el cursor dentro de ese campo) o
modifiquemos el texto (al introducir el texto y salir del campo).
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>DWEC05 - Propiedad VALUE de un objeto de tipo texto</title>
<script type="text/javascript">
function convertirMayusculas(){
/*
En este ejemplo accedemos a la propiedad value de un objeto con id nombre y le
asignamos su contenido actual pero convertido a mayúsculas con el método
toUpperCase() del objeto String.
*/
document.getElementById("nombre").value=document.getElementById("nombre").
value.toUpperCase();
}
</script>
</head>
<body>
<h1>Propiedad VALUE de un objeto INPUT de tipo TEXT</h1>
<form id="formulario" action="pagina.php">
<p>
<label for="nombre">Nombre y Apellidos: </label>
<input type="text" id="nombre" name="nombre" value="" size="30"
onblur="convertirMayusculas()">
</p>
Introduce tu Nombre y Apellidos y haz click fuera del campo.
</form>
</body>
</html>
-7-
Diseño Web en Entorno Cliente DAW
Además de los métodos anteriores, los campos de tipo texto también soportan todas las propiedades
estándar, métodos y eventos.
http://www.w3schools.com/jsref/dom_obj_all.asp
http://www.htmlquick.com/es/reference/tags/input.html
Por ejemplo:
<label for="cantidad">Si desea recibir 20 Kg marque esta opción: </label>
<input type="checkbox" id="cantidad" name="cantidad" value="20 Kg">
Si chequeamos este checkbox y enviamos el formulario, el navegador enviará el par name/value
" cantidad " y " 20 Kg ". Si el checkbox no está marcado, entonces este campo no será enviado en el
formulario. El texto del label se mostrará en la pantalla pero las etiquetas label no se envían al
servidor. Para saber si un campo de tipo checkbox está o no marcado, disponemos de la propiedad
checked . Esta propiedad contiene un valor booleano: true si el campo está marcado o false si no
está marcado. Con esta propiedad es realmente sencillo comprobar o ajustar la marca en un campo
de tipo checkbox .
-8-
Gestión de eventos y formularios en JavaScript Tema 5
Ejemplo:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>DWEC05 - Trabajando con objetos input de tipo radio</title>
<script type="text/javascript">
function mostrarDatos(){
for (var i=0;i<document.formulario.actores.length; i++){
if (document.formulario.actores[i].checked)
alert(document.formulario.actores[i].value);
}
}
</script>
</head>
<body>
<h1>Trabajando con objetos input de tipo radio</h1>
<form name="formulario" action="stooges.php">
<fieldset>
<legend>Selecciona tu actor favorito:</legend>
<input type="radio" name="actores" id="actor-1" value="Walter Bruce Willis - 19
de Marzo de 1955" checked>
<label for="actor-1">Willis</label>
-9-
Diseño Web en Entorno Cliente DAW
Algunas propiedades pertenecen al objeto select al completo, mientras que otras, por ejemplo, sólo
se pueden aplicar a las opciones individuales dentro de ese objeto. Si lo que quieres hacer es
detectar la opción seleccionada por el usuario, y quieres usar JavaScript, tendrás que utilizar
propiedades tanto de select , como de option .
La propiedad más importante del objeto select es la propiedad selectedIndex , a la que puedes
acceder de las siguientes formas:
objetoFormulario.nombreCampoSelect.selectedIndex
document.getElementById("objetoSelect").selectedIndex
El valor devuelto por esta propiedad, es el índice de la opción actualmente seleccionada, y por
supuesto recordarte que los índices comienzan en la posición 0. Siempre que queramos acceder a la
opción actualmente seleccionada, recuerda que tendrás que usar esta propiedad.
Las opciones tienen dos propiedades accesibles que son text y value , y que te permitirán acceder al
texto visible en la selección y a su valor interno para esa opción (ejemplo: <option
value="OU">Ourense</option> ). Veamos las formas de acceso a esas propiedades:
objetoFormulario.nombreCampoSelect.options[n].text
objetoFormulario.nombreCampoSelect.options[n].value
http://www.htmlquick.com/es/reference/tags/select.html
- 10 -
Gestión de eventos y formularios en JavaScript Tema 5
Por ejemplo:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>Uso de la palabra reservada this</title>
<script type="text/javascript">
function identificar(objeto){
var atrName=objeto.name;
var atrId=objeto.id;
var atrValue=objeto.value;
var atrType=objeto.type;
alert("Datos del campo pulsado:\n\nName: "+atrName+"\nID: "+atrId+"\nValue:
"+atrValue+"\nType: "+atrType);
}
</script>
</head>
<body>
<h1>Trabajando con this</h1>
<form id="formulario" action="pagina.php">
<p>
<label for="nombre">Nombre: </label>
<input type="text" name="nombre" id="nombre" value="Constantino"
onclick="identificar(this)"/>
<label for="apellidos">Apellidos: </label>
<input type="text" name="apellidos" id="apellidos" value="Veiga Perez"
onclick="identificar(this)"/>
<label for="edad">Edad: </label>
<input type="password" name="edad" id="edad" value="55"
onclick="identificar(this)"/>
<label for="pais">Pais: </label>
España <input type="radio" name="pais" id="pais1" value="ES"
onclick="identificar(this)"/>
Francia <input type="radio" name="pais" id="pais2" value="FR"
onclick="identificar(this)"/>
</p>
Haga click en cada uno de los campos para ver más información.
</form>
</body>
</html>
En este ejemplo, cada vez que hagamos click en alguno de los objetos, llamaremos a la función
identificar() y a esa función le pasaremos como parámetro this , que en este caso será la
referencia al objeto en el cuál hemos hecho click. La función identificar() recibe ese parámetro, y
lo almacena en la variable objeto, la cuál le permite imprimir todas las referencias al name , id , value
- 11 -
Diseño Web en Entorno Cliente DAW
y type . En el siguiente apartado veremos los eventos y allí te mostraré otro uso de this por ejemplo
dentro de la función identificar() sin tener que pasar ningún parámetro.
"Nunca consideres el estudio como un deber, sino como una oportunidad para penetrar en el
maravilloso mundo del saber."
EINSTEIN, Albert
- 12 -
Gestión de eventos y formularios en JavaScript Tema 5
3.- Eventos.
Caso práctico
La mayor parte de las veces que un usuario realiza acciones en un formulario está generando
eventos. Por ejemplo, cuando hace click con el ratón, cuando sitúa el cursor en un campo, cuando
mueve el ratón sobre algún objeto, etc.
Con JavaScript podremos programar que, cuando se produzca alguno de esos eventos, realice una
tarea determinada. Es lo que se conoce en programación como capturar un evento.
Los modelos de registro de esos eventos, así como el orden en el que esos eventos se generan, es la
parte que va a estudiar Antonio ahora mismo. Esta parte le ayudará mucho cuando tenga que
capturar eventos que se produzcan en secuencia, o cuando quiera cancelar un evento, etc.
Hay que tener en cuenta que, sin eventos prácticamente no hay scripts. En casi todas las páginas web
que incorporan JavaScript, suele haber eventos programados que disparan la ejecución de dichos
scripts. La razón es muy simple, JavaScript fue diseñado para añadir interactividad a las páginas: el
usuario realiza algo y la página reacciona.
Por lo tanto, JavaScript necesita detectar de alguna forma las acciones del usuario para saber cuándo
reaccionar. También necesita saber las funciones, que queremos que ejecute cuando se produzcan
esas acciones.
Cuando el usuario hace algo se produce un evento. También habrá algunos eventos que no están
relacionados directamente con acciones de usuario: por ejemplo el evento de carga ( load ) de un
documento, que se producirá automáticamente cuando un documento ha sido cargado.
Todo el tema de gestión de eventos se popularizó a raíz de la versión 2 de Netscape, que también
soportaba eventos. Netscape 2 soportaba solamente algunos eventos. Los eventos mouseOver y
mouseOut , se hicieron muy famosos a raíz de su utilización para hacer el efecto de sustitución de una
imagen por otra al pasar el ratón por encima. Todo el resto de navegadores, incluido Explorer,
tuvieron que adaptarse a la forma en la que Netscape 2 y 3 gestionaban los eventos.
Aunque hoy en día la técnica de gestión de eventos varía con el objetivo de independizar el código de
JavaScript de la estructura HTML, los navegadores todavía son compatibles con las técnicas utilizadas
por Netscape.
Anteriormente, a las versiones 4 de los navegadores, los eventos (interacciones del usuario y del
sistema), eran capturados preferentemente por gestores de eventos definidos como atributos en las
etiquetas HTML (modelo de eventos en línea). Por ejemplo, cuando un usuario hacía click en un
botón, el evento de onclick que se había programado en la etiqueta HTML era disparado. Ese evento
hacía una llamada a una función en la que se realizarían las operaciones programadas por el usuario.
Aunque todo ese modo de gestión de eventos sigue funcionando, los navegadores modernos ya
incorporan un modelo de eventos, que proporciona un montón de información sobre cómo ocurre
un evento. Estas propiedades son accesibles a través de JavaScript, permitiendo programar
respuestas más inteligentes a las interacciones del usuario con los objetos del documento.
Muchas veces, lo que se hacía en un principio antes de programar cualquier evento, era detectar qué
navegador estábamos utilizando, para saber si nuestro navegador soportaba, o no, los métodos y
propiedades que queríamos usar. Por ejemplo:
if (Netscape) {
utilizar modelo Netscape
}
else if (Explorer) {
- 13 -
Diseño Web en Entorno Cliente DAW
Pero hoy en día ni ésto ni el modelo de detección basado en DHTML se recomiendan debido a las
diferencias que hay entre todos los navegadores actuales. Por lo tanto hay que intentar usar modelos
de detección de eventos estándar y que sean los navegadores los que tengan que adaptarse a ese
modelo.
Cuando hacemos click en el enlace, se llama al gestor de eventos onClick (al hacer click) y se ejecuta
el script; que contiene en este caso una alerta de JavaScript. También se podría realizar lo mismo
pero llamando a una función:
<A href="pagina.html" onClick="alertar()">Pulsa aqui</a>
function alertar(){
alert("Has pulsado en el enlace");
}
La mezcla de minúsculas y mayúsculas en los nombres de evento ( onClick , onMouseOver ) es sólo por
tradición, ya que HTML es insensible a mayúsculas y minúsculas. En cambio en XHTML, sí que los
atributos tendrán que ir obligatoriamente siempre en minúsculas: tienes que escribir onclick y
onmouseover . Es muy importante que te fijes en esto, ya que probablemente trabajarás con XHTML y
deberás cumplir el estándar: "todos los nombres de atributos irán siempre en minúscula".
Este modelo no se recomienda, y aunque lo has visto en ejemplos que hemos utilizado hasta ahora,
tiene el problema de que estamos mezclando la estructura de la página web con la programación de
la misma, y lo que se intenta hoy en día es separar la programación en JavaScript, de la estructura
HTML, por lo que este modelo no nos sirve.
A veces es interesante el bloquear o evitar que se ejecute la acción por defecto. Por ejemplo, en
nuestro caso anterior podríamos evitar que nos conecte con la nueva pagina.html. Cuando
programamos un gestor de eventos, ese gestor podrá devolver un valor booleano true o false . Eso
tendremos que programarlo con la instrucción return true|false . False quiere decir "no ejecutes la
acción por defecto". Por lo tanto nuestro ejemplo quedará del siguiente modo:
<A href="pagina.html" onClick="alertar(); return false">Pulsa aqui</a>
- 14 -
Gestión de eventos y formularios en JavaScript Tema 5
De esa forma, cada vez que pulsemos en el enlace realizará la llamada a la función alertar() y
cuando termine ejecutará la instrucción " return false ", que le indicará al navegador que no ejecute
la acción por defecto asignada a ese objeto (en este caso la acción por defecto de un hiperenlace es
conectarnos con la página href de destino).
También sería posible que nos preguntara si queremos o no queremos ir a la pagina.html. Eso
podríamos hacerlo sustituyendo true o false por una función que devuelva true o false según la
respuesta que demos al " confirm ":
<A href="pagina.html" onClick="return preguntar()">Pulsa aqui</a>
function preguntar(){
return confirm("¿Desea realmente ir a esa dirección?");
}
Esta forma de registro, no fue estandarizada por el W3C, pero debido a que fue
ampliamente utilizada por Netscape y Microsoft, todavía es válida hoy en día.
La ventaja de este modelo es que podremos asignar un evento a un objeto
desde JavaScript, con lo que ya estamos separando el código de la estructura.
Fíjate que aquí los nombres de los eventos sí que van siempre en minúsculas.
elemento.onclick = hacerAlgo;
Otra gran ventaja es que, como el gestor de eventos es una función, podremos
realizar una llamada directa a ese gestor, con lo que estamos disparando el evento de forma manual.
Por ejemplo:
elemento.onclick();
// Al hacer ésto estamos disparando el evento click de forma manual y se ejecutará la función
hacerAlgo()
SIN PARÉNTESIS
Fíjate que en el registro del evento no usamos paréntesis (). El método onclick espera que se le
asigne una función completa. Si haces: element.onclick = hacerAlgo() ; la función será ejecutada y el
resultado que devuelve esa función será asignado a onclick . Pero ésto no es lo que queremos que
haga, queremos que se ejecute la función cuando se dispare el evento.
En el modelo en línea podemos utilizar la palabra reservada this cuando programamos el gestor de
eventos. Por ejemplo:
<A href="pagina.html" ID="mienlace" onClick="alertar(this)">Pulsa aqui</a>
<script type="text/javascript">
function alertar(objeto){
alert("Te conectaremos con la página: "+objeto.href);
}
- 15 -
Diseño Web en Entorno Cliente DAW
</script>
<script type="text/javascript">
document.getElementById("mienlace").onclick = alertar;
function alertar(){
alert("Te conectaremos con la página: "+this.href);
}
</script>
Fíjate que estamos usando this dentro de la función, sin pasar ningún objeto (tal y como hacíamos
en el modelo en línea). En el modelo tradicional el this que está dentro de la función, hace
referencia al objeto donde hemos programado el evento. También hay que destacar que en este
modelo es importante que el hiperenlace sea declarado antes de programar la asignación onclick , ya
que si por ejemplo escribimos el hiperenlace después del bloque de código de JavaScript, éste no
conocerá todavía el objeto y no le podrá asignar el evento de onclick . Esto también se podría
solucionar, programando la asignación de eventos a los objetos, en una función que se ejecute
cuando el documento esté completamente cargado. Por ejemplo con window.onload=asignarEventos .
Si por ejemplo queremos que cuando se produzca el evento se realicen llamadas a más de una
función lo podremos hacer de la siguiente forma:
elemento.onclick = function {llamada1; llamada2 };
Este método tiene tres argumentos: el tipo de evento, la función a ejecutar y un valor booleano
( true o false ), que se utiliza para indicar cuándo se debe capturar el evento: en la fase de captura
( true ) o de burbujeo ( false ). En el apartado 3.5 veremos en detalle la diferencia entre estas dos
fases.
elemento.addEventListener('evento', función, false|true)
Por ejemplo para registrar la función alertar() de los ejemplos anteriores, haríamos:
document.getElementById("mienlace").addEventListener('click',alertar,false);
function alertar(){
alert("Te conectaremos con la página: "+this.href);
}
La ventaja de este método, es que podemos añadir tantos eventos como queramos. Por ejemplo:
document.getElementById("mienlace").addEventListener('click',alertar,false);
document.getElementById("mienlace").addEventListener('click',avisar,false);
document.getElementById("mienlace").addEventListener('click',chequear,false);
Por lo tanto, cuando hagamos click en "mienlace" se disparará la llamada a las tres funciones. Por
cierto, el W3C no indica el orden de disparo, por lo que no sabemos cuál de las tres funciones se
ejecutará primero. Fíjate también, que el nombre de los eventos al usar addEventListener no lleva
'on' al comienzo.
También se pueden usar funciones anónimas (sin nombre de función), con el modelo W3C:
element.addEventListener('click', function () {
this.style.backgroundColor = '#cc0000';
- 16 -
Gestión de eventos y formularios en JavaScript Tema 5
}, false)
La palabra reservada this , tiene exactamente la misma funcionalidad que hemos visto en el modelo
tradicional.
¿QUÉ EVENTOS HAN SIDO REGISTRADOS ?
Uno de los problemas de la implementación del modelo de registro del W3C, es que no podemos
saber con antelación, los eventos que hemos registrado a un elemento.
El W3C en el reciente nivel 3 del DOM, introdujo un método llamado eventListenerList , que
almacena una lista de las funciones que han sido registradas a un elemento. Tienes que tener
cuidado con este método, porque no está soportado por todos los navegadores.
Comparando este modelo con el del W3C tenemos dos diferencias importantes:
Los eventos siempre burbujean, no hay forma de captura.
La función que gestiona el evento está referenciada, no copiada, con lo que la palabra reservada
this siempre hace referencia a window y será completamente inútil.
Como resultado de estas dos debilidades, cuando un evento burbujea hacia arriba es imposible
conocer cuál es el elemento HTML que gestionó ese evento.
Listado de atributos de eventos (IE: Internet Explorer, F: Firefox, O: Opera, W3C: W3C Standard.)
Listado de atributos de eventos
Atributo El evento se produce cuando... IE F O W3C
onblur Un elemento pierde el foco. 3 1 9 Sí
onchange El contenido de un campo cambia. 3 1 9 Sí
onclick Se hace click con el ratón en un objeto. 3 1 9 Sí
ondblclick Se hace doble click con el ratón sobre un objeto. 4 1 9 Sí
- 17 -
Diseño Web en Entorno Cliente DAW
Imagina que tenemos un elemento contenido dentro de otro elemento, y que tenemos programado
el mismo tipo de evento para los dos (por ejemplo el evento click). ¿Cuál de ellos se disparará
primero? Sorprendentemente, esto va a depender del tipo de navegador que tengamos.
Modelo W3C
W3C decidió tomar una posición intermedia. Así supone que, cuando se produce un evento en su
modelo de eventos, primero se producirá la fase de captura hasta llegar al elemento de destino, y
luego se producirá la fase de burbujeo hacia arriba. Este modelo es el estándar, que todos los
navegadores deberían seguir para ser compatibles entre sí.
- 18 -
Gestión de eventos y formularios en JavaScript Tema 5
Tú podrás decidir cuando quieres que se registre el evento: en la fase de captura o en la fase de
burbujeo. El tercer parámetro de addEventListener te permitirá indicar si lo haces en la fase de
captura ( true ), o en la fase de burbujeo( false ).
Por ejemplo:
elemento1.addEventListener('click',hacerAlgo1,true);
elemento2.addEventListener('click',hacerAlgo2,false);
Para detener la propagación del evento en la fase de burbujeo, disponemos del método
stopPropagation() . En la fase de captura es imposible detener la propagación.
- 19 -
Diseño Web en Entorno Cliente DAW
Hay dos métodos principales de validación de formularios: en el lado del servidor (usando scripts
CGI, PHP, ASP, etc.) y en el lado del cliente (generalmente usando JavaScript).
La validación en el lado del servidor es más segura, pero a veces también es más complicada de
programar, mientras que la validación en el lado del cliente es más fácil y más rápida de hacer (el
navegador no tiene que conectarse al servidor para validar el formulario, por lo que el usuario
recibirá información al instante sobre posibles errores o fallos encontrados).
La idea general que se persigue al validar un formulario, es que cuando se envíen los datos al
servidor, éstos vayan correctamente validados, sin ningún campo con valores incorrectos.
A la hora de programar la validación, podremos hacerlo a medida que vamos metiendo datos en el
formulario, por ejemplo campo a campo, o cuando se pulse el botón de envío del formulario.
La validación de datos del usuario en la entrada, generalmente suele fallar en alguna de las 3
siguientes categorías:
Existencia: comprueba cuando existe o no un valor.
Numérica: que la información contenga solamente valores numéricos.
Patrones: comprueba que los datos sigan un determinado patrón, como el formato de un e-mail,
una fecha, un número de teléfono, un número de la seguridad social, etc.
JavaScript también se puede utilizar para modificar los elementos de un formulario, basándose en los
datos introducidos por el usuario: tal como cubrir un campo de selección con una lista de nombres
de ciudades, cuando una determinada provincia está seleccionada, etc.
Una parte muy importante que no debes olvidar al usar JavaScript con formularios, es la posibilidad
de que el usuario desactive JavaScript en su navegador, por lo que JavaScript no debería ser una
dependencia en la acción de envío de datos desde un formulario.
- 20 -
Gestión de eventos y formularios en JavaScript Tema 5
La validación de un formulario en el lado del cliente puede ahorrar algunas idas y vueltas a la hora de
enviar los datos, pero aún así, tendrás que realizar la validación de datos en el servidor, puesto que
es allí realmente donde se van a almacenar esos datos y el origen de los mismos puede venir por
cauces que no hemos programado.
validacionFormulario.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>DWEC05 - CONT_R22 Validacion de un Formulario</title>
<script type="text/javascript" src="validacionFormulario.js"></script>
<style type="text/css">
label{
width: 150px;
float:left;
margin-bottom:5px;
}
input,select {
width:150px;
float:left;
margin-bottom:5px;
}
fieldset{
background:#CCFF99;
width:350px;
}
.error{
border: solid 2px #FF0000;
}
</style>
</head>
<body>
<fieldset>
<legend>DWEC05 - Validación de un Formulario -</legend>
<form name="formulario" id="formulario" action="http://www.google.es" method="get">
<label for="nombre">Nombre:</label>
<input type="text" name="nombre" id="nombre" />
<label for="apellidos">Apellidos:</label>
<input type="text" name="apellidos" id="apellidos" />
<label for="edad">Edad:</label>
<input name="edad" type="text" id="edad" maxlength="3" />
<label for="matricula">Matrícula Coche:</label>
<input name="matricula" type="text" id="matricula" value="XXXX AAA" />
<label for="provincia">Provincia:</label>
<select name="provincia" id="provincia">
<option value="0" selected="selected">Seleccione Provincia</option>
<option value="H">Huesca</option>
<option value="ZA">Zaragoza</option>
<option value="T">Teruel</option>
</select>
<input type="reset" name="limpiar" id="limpiar" value="Limpiar" />
<input type="submit" name="enviar" id="enviar" value="Enviar" />
</form>
</fieldset>
- 21 -
Diseño Web en Entorno Cliente DAW
</body>
</html>
validacionFormulario.js
// Ésta es la primera instrucción que se ejecutará cuando el documento esté cargado.
// Se hará una llamada a la función iniciar(), de esta manera nos aseguramos que las
// asignaciones de eventos no fallarán ya que todos los objetos están disponibles.
window.onload=iniciar;
//----------------------------------------------------------//
function iniciar(){
// Al hacer click en el botón de enviar tendrá que llamar a la la función validar que
// se encargará de validar el formulario.
// El evento de click lo programamos en la fase de burbujeo (false).
document.getElementById("enviar").addEventListener('click',validar,false);
}
//----------------------------------------------------------//
function validar(eventopordefecto) {
// En la variable eventopordefecto gestionaremos el evento por defecto asociado al botón de
// "enviar" (type=submit) que en este caso lo que hace por defecto es enviar un formulario.
// Validamos cada uno de los apartados con llamadas a sus funciones correspondientes.
if (validarcampostexto(this) && validarMatricula() && validarProvincia() &&
confirm("¿Deseas enviar el formulario?"))
return true;
else
{
// Cancelamos el evento de envío por defecto asignado al boton de submit enviar.
eventopordefecto.preventDefault();
return false; // Salimos de la función devolviendo false.
}
}
//----------------------------------------------------------//
function validarcampostexto(objeto){
// A esta función le pasamos un objeto (que en este caso es el botón de enviar.
// Puesto que validarcampostexto(this) hace referencia al objeto dónde se programó ese
// evento que fue el botón de enviar.
var formulario = objeto.form; // La propiedad form del botón enviar contiene la
referencia del formulario dónde está ese botón submit.
for (var i=0; i<formulario.elements.length; i++){
// Eliminamos la clase Error que estuviera asignada a algún campo.
formulario.elements[i].className="";
}
// De esta manera podemos recorrer todos los elementos del formulario, buscando los que son
// de tipo texto para validar que contengan valores.
for (var i=0; i<formulario.elements.length; i++) {
if (formulario.elements[i].type == "text" && formulario.elements[i].value=="") {
alert("El campo: "+formulario.elements[i].name+" no puede estar en blanco");
formulario.elements[i].className="error";
formulario.elements[i].focus();
return false;
}
// Aprovechamos y dentro de la función validamos también la edad.
else if (formulario.elements[i].id=="edad"){
if (isNaN(formulario.elements[i].value) || formulario.elements[i].value <0 ||
formulario.elements[i].value >105) {
alert("El campo: "+formulario.elements[i].name+" posee valores incorrectos o la
edad <0 o >105");
formulario.elements[i].className="error";
formulario.elements[i].focus();
return false;
}
}
}
return true; // Si sale de la función con esta instrucción es que todos los campos de
texto y la edad son válidos.
}
//----------------------------------------------------------//
function validarMatricula(){
// 4 Números 1 espacio en blanco(opcional) y 3 letras de la A-Z en mayúsculas
var patron = /^\d{4}\s?[A-Z]{3}$/;
- 22 -
Gestión de eventos y formularios en JavaScript Tema 5
if (patron.test(document.getElementById("matricula").value)) {
document.getElementById("matricula").className="";
return true;
}else{
alert("El campo: Matricula no está correcto.\n\nCuatro números espacion en blanco
opcional y 3 letras mayúsculas.");
// Situamos el foco en el campo matrícula y le asignamos la clase error.
document.getElementById("matricula").focus();
document.getElementById("matricula").className="error";
return false;
}
}
//----------------------------------------------------------//
function validarProvincia(){
// Comprueba que la opción seleccionada sea diferente a 0.
// Si es la 0 es que no ha seleccionado ningún nombre de Provincia.
if (document.getElementById("provincia").selectedIndex==0) {
alert("Atención!: Debes seleccionar una provincia.");
// Situamos el foco en el campo provincia y le asignamos la clase error.
document.getElementById("provincia").focus();
document.getElementById("provincia").className="error";
return false;
}else
return true;
}
- 23 -
Diseño Web en Entorno Cliente DAW
¿Cuáles de los siguientes métodos son, los que se utilizan en el modelo de registro de
eventos de la W3C?
addEventListener() onClick() removeEventListener()
attachEvent() detachEvent()
Sólo addEventListener() y removeEventListener() son métodos utilizados en el registro de eventos de W3C. OnClick() no sería válido por
ser un atributo de evento y además tendría que ir en minúsculas y las opciones attachEvent y detachEvent pertenecen al modelo de
registro de eventos de Microsoft.
- 24 -
Gestión de eventos y formularios en JavaScript Tema 5
LAS EXPRESIONES REGULARES SON PATRONES DE BÚSQUEDA, QUE SE PUEDEN UTILIZAR PARA ENCONTRAR TEXTO QUE
COINCIDA CON EL PATRÓN ESPECIFICADO.
Este código funciona porque estamos buscando una subcadena de texto exacta. ¿Pero qué pasaría si
hiciéramos una búsqueda más general? Por ejemplo si quisiéramos buscar la cadena "car" en textos
como "cartón", "bicarbonato", "practicar", ...?
CUANDO ESTAMOS BUSCANDO CADENAS QUE CUMPLEN UN PATRÓN EN LUGAR DE UNA CADENA EXACTA,
NECESITAREMOS USAR EXPRESIONES REGULARES.
Podrías intentar hacerlo con funciones de String , pero al final, es mucho más sencillo hacerlo con
expresiones regulares, aunque la sintaxis de las mismas es un poco extraña y no necesariamente muy
amigable.
En JavaScript las expresiones regulares se gestionan a través del objeto RegExp .
Para crear un literal del tipo RegExp , tendrás que usar la siguiente sintaxis:
var expresion = /expresión regular/;
La expresión regular está contenida entre la barras / , y fíjate que no lleva comillas. Las comillas sólo
se pondrán en la expresión regular, cuando formen parte del patrón en sí mismo.
Las expresiones regulares están hechas de caracteres, solos o en combinación con caracteres
especiales, que se proporcionarán para búsquedas más complejas. Por ejemplo, lo siguiente es una
expresión regular que realiza una búsqueda que contenga las palabras Aloe Vera, en ese orden y
separadas por uno o más espacios en medio:
var expresion=/Aloe\s+Vera/;
Los caracteres especiales en este ejemplo son, la barra invertida ( \ ), que tiene dos efectos: o bien se
utiliza con un carácter regular, para indicar que se trata de un carácter especial, o se usa con un
carácter especial, tales como el signo más ( + ), para indicar que el carácter debe ser tratado
- 25 -
Diseño Web en Entorno Cliente DAW
literalmente. En este caso, la barra invertida se utiliza con " s ", que transforma la letra s en un
carácter especial indicando un espacio en blanco, un tabulador, un salto de línea, etc. El símbolo +
indica que el carácter anterior puede aparecer una o más veces.
- 26 -
Gestión de eventos y formularios en JavaScript Tema 5
no es un espacio en blanco
\t Un tabulador
(x) Capturando paréntesis Recuerda los caracteres.
\r Un retorno de carro
Cualquier cadena que está
/la(?=
?=n seguida por la cadena n Hola mundo mundial.
mundo)
indicada después del igual.
Usaremos el objeto, cuando sabemos que la expresión regular va a cambiar, o cuando vamos a
proporcionarla en tiempo de ejecución.
Al igual que otros objetos en JavaScript, el objeto RegExp también tiene sus propiedades y métodos:
Propiedades del objeto RegExp
Propiedad Descripción
global Especifica que sea utilizado el modificador "g".
ignoreCase Especifica que sea utilizado el modificador "i".
lastIndex El índice donde comenzar la siguiente búsqueda.
multiline Especifica si el modificador "m" es utilizado.
source El texto de la expresión regular RegExp.
Métodos del objeto RegExp
Método Descripción
compile() Compila una expresión regular.
exec() Busca la coincidencia en una cadena. Devolverá la primera coincidencia.
test() Busca la coincidencia en una cadena. Devolverá true o false .
validación.html
<html>
<head>
<meta charset="utf-8">
<title>Ejemplo de formulario</title>
<script type="text/javascript" src="validacion.js"></script>
</head>
<body>
<form name="formulario" id="formulario" method="post" action="">
<p>
<label for="nombre">Nombre;</label>
<input type="text" name="nombre" id="nombre">
</p>
<p>
<label for telefono">Teléfono:</label>
<input type="text" name="telefono" id="telefono">
</p>
<p>
<label for="matricula">Matrícula coche:</label>
<input type="text" name="matricula" id="matricula">
</p>
<p>
<input type="reset" name="button" id="button" value="Restablecer">
<input type="button" name="enviar" id="enviar" value="Enviar">
- 27 -
Diseño Web en Entorno Cliente DAW
<br />
</p>
</form>
</body>
</html>
validación js
window.onload=iniciar;
function iniciar(){
document.getElementById("enviar").addEventListener('click',validar,false);
}
function validar(){
// Teléfono: 123456789
var patronTelefono= /^\d{9}$/;
if (patronTelefono.test(document.getElementById("telefono").value)){
if(patronMatricula.test(document.getElementById("matricula").value)){
if(confirm("¿Desea enviar el formulario?")){
document.getElementById("formulario").submit();
}
}else{
alert("Error: campo matricula incorrecta");
}
}else{
alert("Error: campo telefono incorrecto");
}
}
<!DOCTYPE html>
- 28 -
Gestión de eventos y formularios en JavaScript Tema 5
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>Ejemplos de RegExp</title>
<script type="text/javascript">
window.onload=iniciar;
// Cuando se termine de cargar el documento,llamará a la función iniciar().
// En esa función programaremos el evento de click para el botón comprobar.
// Si no esperamos a que se cargue el documento, el botón no estará disponible
// y fallará el acceso a document.getElementByid("comprobar"), ya que todavía no
// conoce ese objeto.
function iniciar(){
document.getElementById("comprobar").onclick=comprobar;
}
function comprobar(){
var numero = document.getElementById("ssn").value;
var patron = /^\d{3}-?\d{2}-?\d{3}$/;
if (numero.match(patron))
alert("Correcto: el número "+numero+" cumple el estándar americano");
else
alert("Error: el número "+numero+" NO cumple el estandar.");
}
</script>
</head>
<body>
<form name="formulario">
<label for="ssn">Número Seguridad Social Americano:</label>
<input type="text" name="ssn" id="ssn" />
<input type="button" name="comprobar" id="comprobar" value="Comprobar Formato" />
</form>
</body>
</html>
- 29 -
Diseño Web en Entorno Cliente DAW
Permitir que algún programa pueda leer y escribir en el disco duro puede dar que pensar en un
principio, pero el mecanismo de las cookies es algo más seguro, ya que no abre tu disco duro al
mundo para que cualquiera pueda ver su contenido o modificarlo. Este mecanismo de las cookies
proporciona acceso a un fichero de texto (en Internet Explorer) o a un fichero especial (en otros
navegadores distintos a Internet Explorer), que está situado en un directorio especial del disco duro.
Internet Explorer para Windows usa un sistema diferente: todas las cookies para cada dominio se
almacenarán en un fichero específico de dominio dentro del directorio C:\Windows\Temporary
Internet Files\ . Los ficheros comienzan con el nombre de Cookie : e incluyen el usuario y dominio
del servidor que escribió la cookie.
Google Chrome almacena las cookies en su base de datos SQLite en un fichero llamado Cookies
dentro de [user] \ Local Settings \ Application Data \ Google \ Chrome \ User Data \ Default .
Tienes que tener precaución con Chrome ya que este navegador deshabilita las cookies si no
accedemos a través de http://
- 30 -
Gestión de eventos y formularios en JavaScript Tema 5
LAS COOKIES SON ESPECÍFICAS AL DOMINIO. En otras palabras, si un dominio crea una cookie, otro
dominio no podrá acceder a ella a través del navegador. La razón de ello es que muchas veces
podremos almacenar datos importantes como usuarios/contraseñas en las cookies, y no queremos
que otros dominios puedan consultarlos. La mayor parte de las veces, cuando almacenamos datos de
este tipo, estarán encriptados dentro de lacookie.
LAS COOKIES TENDRÁN UNA FECHA DE CADUCIDAD, ya que algunos navegadores tienen limitado el
número máximo de cookies que pueden almacenar (1000 en Firefox). Será el propio navegador el
encargado de borrar las cookies caducadas.
Para grabar datos en un fichero de cookie, podemos utilizar una asignación simple con la propiedad
document.cookie . Pero tendrás que tener mucha precaución con el formato de datos, ya que si no la
cookie no será grabada correctamente. Aquí te muestro la sintaxis de cómo se asignaría un valor a
una cookie (los campos opcionales van entre corchetes; en cursiva irán las posiciones para escribir
nuestros propios datos):
document.cookie = "nombreCookie=datosCookie
[; expires=horaformatoGMT]
[; path=ruta]
[; domain=nombreDominio]
[; secure]"
Cada cookie deberá tener un nombre y un texto asignado (aunque sea cadena vacía ""). Por ejemplo
si quieres almacenar la cadena "Martin" para una cookie "usuario", haríamos:
document.cookie = "usuario=Martin";
El navegador ve que no tenemos ninguna cookie con este nombre, la creará automáticamente; si la
cookie ya existe, entonces la reemplazará. Se pueden omitir el resto de parámetros de la cookie; en
ese caso el navegador usará valores por defecto. Para cookies temporales generalmente sólo
necesitaremos escribir nombre/valor. Es decir estas cookies durarán solamente el tiempo de la
sesión. Si por ejemplo cerramos el navegador y lo volvemos a abrir la cookie desaparece.
Ejemplo:
document.cookie="contador=0";
// Almacena contador=0 en la cookie sin ningún otro contenido a mayores.
El dominio domain si no se pone, se asignará por defecto el dominio de la página que creó la cookie.
Si se omite el valor secure , ésto implica que nuestra cookie será accesible por cualquier programa en
nuestro dominio que se ajuste a las propiedades de dominio y path .
Para recuperar los datos de una cookie tendremos que acceder a la propiedad document.cookie e
imprimir su valor. Los resultados nos llegarán en forma de cadena de texto. Por ejemplo una cadena
de texto document.cookie podría tener el siguiente aspecto:
usuario=Martin; password=OjYgdjUA
- 31 -
Diseño Web en Entorno Cliente DAW
En otras palabras no podremos tratar las cookies como objetos. En su lugar, deberemos pasar la
cadena de texto de la cookie, y extraer los datos necesarios de su contenido.
Cada vez que nuestro ordenador pide una página a un servidor, este realiza una conexión nueva con
el servidor, por lo cual, el servidor no tiene conocimiento de las anteriores acciones del visitante (Por
ejemplo logins).
Para resolver eso, nació un tipo de archivo, llamado cookie, que se almacena en el ordenador del
visitante y puede contener información sobre nuestros movimientos.
Así, una vez entramos a un servicio con nuestro nombre y contraseña, el servidor, nos suele
identificar con un número al azar que es guardado en el servidor y enviado a la vez al usuario, de
manera que con ese número, puede conocer nuestro nombre, contraseña...
Así por ejemplo podemos guardar una cookie llamada ID con valor 123456 con caducidad el 2 de
Diciembre del 2014:
document.cookie="ID = 123456; expires = 2 Dec 2014 23:59:59 GMT"
En cambio para leer una cookie deberemos crear una función especial:
function leerCookie(nombre) {
a = document.cookie.substring(document.cookie.indexOf(nombre + '=') + nombre.length +
1,document.cookie.length);
if(a.indexOf(';') != -1)a = a.substring(0,a.indexOf(';'))
return a;
}
¿Te has parado a pensar que pasaría si el usuario bloquea en el navegador las cookies o JavaScript?
- 32 -