Los formularios son un componente a veces esencial en una página web, ya que permiten la interacción con el usuario, pudiendo conseguir mediante ellos recoger información particular sobre sus gustos, opiniones, datos personales, etc, información que luego deberemos procesar en el servidor web para su correcta interpretación y uso.
Este proceso de datos se puede llevar a cabo mediante diferentes tecnologías: CGI, ASP, JSP, etc.
Pero si nos limitamos al proceso de datos y elementos de formulario en el lado del cliente, la herramienta más poderosa con la que contamos es sin duda alguna el lenguaje JavaScript (o JScript, como gustan llamarlo los sres. de Microsoft).
Mediante JavaScript podemos no sólo validar los datos de cada uno de los campos que formen el formulario, para así poder estar seguros de su validez antes de ser enviados al servidor, si no que también podemos acceder a todos los elementos que forman el formulario y a sus propiedades, con lo que podemos diseñar formularios realmente atractivos y dinámicos, que convertirán nuestras páginas en verdaderas "obras de arte". Y todo esto es posible porque en la propia definición de JavaScript existe un objeto formulario.
Para aquellas personas que aún no estén muy familiarizados con los formularios les remito al Manual de formularios en HTML de este mismo sitio web.
Este artículo - manual no pretende explicar todos los posibles casos de trabajo con formularios en JavaScript, ni mostrar ejemplos complicados en exceso, que más que enseñar algo crearían confusión, si no mostrar las bases de cómo podemos manejar formularios con este lenguaje de programación, dejando al empeño del lector el profundizar más en casos concretos.
El objeto form.-
El objeto form se considera en JavaScript como un subobjeto del objeto document, que a su vez forma parte del objeto predefinido window, por lo que inicialmente la sintaxis para acceder a una cualquiera de sus propiedades o métodos es:
en la que podemos prescindir de las cadenas forms y window, ya que el navegador considera al formulario particular un objeto por sí mismo.
Además, el objeto forms dentro del objeto documents posee dos subpropiedades:
* index, array que contiene todos los formularios de una página, de sintaxis:
document.forms[index]
y donde debemos tener en cuenta que el primer formulario viene indentificado por el índice 0, por lo que para acceder al primer formulario de una página deberemos usar la expresión:
document.forms[0]...
* length , que contiene el número de formularios que hay en la página, y cuya sintaxis es:
document.forms.length
Recordemos que en un formulario HTML un formulario se crea mediante un código del tipo:
Como he dicho antes, un formulario es para JavaScript un objeto por sí mismo, y como tal posee unas propiedades, unos métodos y unos eventos propios, que nos van a permitir acceder a cada uno de los elementos que lo forman y poder modificar su diseño y comportamiento dinámicamente, sin necesidad de hacer nuevas peticiones al servidor, ya que todo se va a ejecutar en el lado cliente, estando todo el código necesario dentro de la propia página web.
Las principales propiedades del objeto form son:
* name : es la propiedad más importante del objeto form, ya que nos va a permitir identificar cada formulario con un nombre identificador único, identificador que vamos a usar luego para poder referirnos sin ambiguedades a un formulario de nuestra página en concreto y acceder a sus propiedades y métodos. Por esto, TODA ETIQUETA FORM DEBE TENER SU PROPIEDAD NAME Y NO PUEDE HABER DOS FORMULARIOS CON EL MISMO NOMBRE EN UNA MISMA PÁGINA.
*
action : esta propiedad define la URL o URI a donde se van a mandar los datos del formulario; es decir, su valor va a ser una cadena que va a definir la ruta relativa o absoluta en dónde se encuentra el programa o página activa que va a procesar los datos contenidos en los diferentes campos del formulario. Sin el uso de JavaScript esta propiedad sería estática, por lo que una vez incluida en el código inicial de la página permanecería inmutable. Pero mediante JavaScript podemos cambiarla, símplemente refiriéndonos a ella mediante la escritura:
esto es especialmente útil cuando por ejemplo debemos mandar los datos del formulario a diferentes páginas JSP dependiendo de uno de los datos introducido en un campo. Como ejemplo, supongamos que en el formulario de nuestra página hay dos checkbox, y que dependiendo de cual marque el usuario debemos enviar los datos bien a la página a.jsp o a la página b.jsp. El código necesario para ello sería:
<HTML>
<HEAD>
<SCRIPT LANGUAGE= "Javascript">
<--
function enviar( ){
if ((document.forms.datos.sistema1.checked = = true) && (document.forms.datos.sistema2.checked = = true){
alert('debe hacer una sóla selección)
{
else if (document.forms.datos.sistema1.checked = = true) document.forms.datos.action = "/jsp/pag_1.jsp"
else if (document.forms.datos.sistema2.checked = = true) document.forms.datos.action="/jsp/pag_2.jsp"
else alert ('debe hacer una selección')
document.forms.datos.submit()
}
</HEAD>
<BODY>
<FORM NAME="datos" ACTION="/jsp/pag_3.jsp" METHOD= "post">
<INPUT TYPE="checkbox" NAME="sistema1">Sistema 1
<INPUT TYPE="checkbox" NAME="sistema2">Sistema 2
<INPUT TYPE="button" VALUE="enviar" ONCLICK="envia( )">
</FORM>
</BODY>
</HTML>
y con esto los datos serían enviados a una u otro página para su proceso, y en caso de que no se hubiera seleccionado ninguna casilla aparecería un mensaje de error. Podemos ver este ejemplo en acción, sólo que en vez de asignar un action en el servidos he asignado a cada casilla como action una página html diferente.
* method : este parámetro establece el método de envío de los datos del formulario. Su valor puede ser POST, conveniente cuando queremos enviar una grán cantidad de datos como una cadena contínua, y que es el más usado, o GET, que se emplea cuando queremos pasar unos datos concretos a una página ASP o JSP (para más información ir al manual de formularios HTML).
También podemos acceder a cambiar esta propiedad dinámicamente, pero no se suele hacer nunca, ya que el método de envío suele estar definido con toda exactitud. No obstante, la sintaxis para acceder a esta propiedad sería:
* target : la propiedad target define el nombre de la ventana o frame en la que se van a cargar los resultados de procesar el formulario; es decir, cuando el usuario pincha el botón submit se envían los datos del formulariio al servidor, en el que un programa o página activa procesa los datos, generando de nuevo otra página que se envía al navegador cliente. En la ventana o frame definido por el atributo target se va a cargar esta página de respuesta.
Nos puede interesar que dependiendo de la clase de resultado que obtengamos al procesar los datos cambie la ventana en la que se va a mostrar la página de respuesta, e incluso definir las posibles ventanas dinámicamente. Como ejemplo, supongamos que tenemos una página inicial con dos frames: uno superior, en dónde inicialmente existe un mensaje orientativo, y otro central, en el que inicialmente se encuentra el formulario que debe completar el usuario. Nos interesa que si marca el primer radio botón de un grupo de dos la página de respuesta sea otra página que se carge en la ventana central, pero que si el radio botón marcado es el segundo la respuesta sea un mensaje determinado que se muestre en el frame superior. Para ello debemos definir primero una página con dos frames, en la que se cargan la página del mensaje inicial arriba y el formulario abajo. El código de la página del formularios es el que sigue:
elements : esta propiedad es un array o vector que contiene todos los elementos que forman un formulario, sean cuales sean, y mediante ella podemos conocer el número de campos diferentes que tiene el formulario, su tipo, etc, teniendo en cuenta que el primer índice del vector es el 0, como ocurría con el vector forms. Posee dos subpropiedades:
* index, que define mediante un índice los diferentes campos que forman el formulario, empezando los índices por el 0, y cuya sintaxis es:
document.forms.nombre_formulario.elements[index]
* length, que contiene el número de elementos que forman el formulario, y cuya sintaxis es:
document.forms.nombre_formulario.elements.length
El uso general de la subpropiedad index puede ser del tipo:
<HTML>
<HEAD>
<SCRIPT language="JavaScript" type="text/javascript">
function campo( ) {
var f = document.forms.primero.elements[0].name;
alert('el nombre del primer campo del primer formulario es '+f);
}
function texto( ) {
var g = document.forms.segundo.elements[1].value;
alert('el texto del segundo campo del segundo formulario es '+g);
}
function cambia( ) {
document.forms[2].elements[0].value='cambiamos el texto';
}
</SCRIPT>
</HEAD>
<BODY>
<FORM NAME="primero">
<INPUT TYPE="text" NAME="texto1" VALUE="formulario 1" SIZE="30">
</form>
<form name="segundo">
<INPUT TYPE="radio" NAME="radio2">
<INPUT TYPE="text" NAME="texto2" VALUE="formulario 2" SIZE="30">
</form>
<form name="tercero">
<INPUT TYPE="text" NAME="texto3" VALUE="formulario 3" SIZE="30"><br><br>
<INPUT TYPE="button" VALUE="nombre campo" ONCLICK="campo()">
<INPUT TYPE="button" VALUE="texto campo" ONCLICK="texto()">
<INPUT TYPE="button" VALUE="cambia texto" ONCLICK="cambia()">
</FORM>
</BODY>
</HTML>
Como vemos en este ejemplo, también podemos referirnos a un formulario de nuestra página por medio de su índice en el array forms que posee cada objeto window.document, teniendo en cuenta que el primer índice es 0 . Mediante esta forma de expresarnos podemos acceder a cualquier formulario de la página sin necesidad de conocer su nombre, y podemos obtener el número de formularios que hay en una página en concreto. La sintaxis para acceder a un formulario mediante este camino es del tipo:
document.forms[indice].propiedad
Y para conocer el nº de formularios en la página deberemos escribir:
function cantidad ( ) {
var f = document.forms.length;
alert( ' el número de formularios de la página es ' + f );
document.forms[2].texto.value='cambiamos el valor del campo';
}
y esto en acción, en una página con 3 formularios en la que mostramos el número de ellos y cambiamos el valor del campo de texto del segundo formulario.
encoding :que es un string o cadena que contiene el tipo MIME utilizado para codificar el contenido del formulario a enviar al servidor, y que refleja el atributo ENCTYPE de la etiqueta FORM de HTML, que se utiliza para codificar los datos remitidos desde el formulario hacia el servidor, pudiendo mediante esta propiedad cambiar dinámicamente lel tipo de codificación.
Los métodos del objeto form son dos:
* submit ( ) : para enviar los datos de un formulario es necesario siempre utilizar este método, que por defecto está asociado al elemento de formulario <INPUT TYPE = " submit " >, que es un botón que al ser pulsado llama al método submit. Ahora bien, a veces nos interesa que antes de que se produzca el envío de datos al servidor se ejecuten una serie de acciones del lado del cliente, como pueden ser validación de datos, mensajes de alerta y/o confirmación, etc. Para lograr esto podemos sustituir el botón tipo submit por un botón tipo button que al ser pulsado llame a una función JavaScript que ejecute las acciones previas al envío y una vez cumplimentadas envíe los datos. Esto se consigue llamando en la función al método submit ( ), y el código necesario tiene el aspecto siguiente:
function previa ( ) {
...
...acciones a realizar...
...
document.forms.nombre_formulario.submit ( );
}
* reset ( ) : este método pone a cero los campos del formulario, es decir, vuelve a situar el formulario en su estado inicial, y al igual que ocurre con el método submit existe por defecto un botón <INPUT TYPE = " reset " > que se encarga de realizar esta operación, útil por ejemplo cuando el usuario se ha equivocado al rellenar los campos y desea comenzar de nuevo el proceso. Pero también nos puede interesar a veces poner a cero los campos del formulario sin que intervenga el usuario. Esto lo conseguimos llamando diréctamente al método submit ( ) o llamando a una función que ejecute el método, siendo el código de llamada en ambos casos del tipo:
document.forms.nombre_formulario.reset ( )
Por último, vamos a ver los eventos que admite el objeto form, algunos de los cuales son estándares y otros sin serlo sí los admite, y que son:
* onSubmit : es el principal evento del objeto y el único estandar, y se produce al enviar los datos del formulario mediante el botón submit o mediante el método submit ( ). Un ejemplo de llamada al método sería:
<FORM NAME = " form1" ACTION = "/cgi/proceso.cgi" ONSUBMIT = " alert ( ' se envían los datos ' ) " >
* onReset : mediante este evento podemos ejecutar una acción dada cuando el usuario pincha el botón de borrado o cuando mediante una función se ha llamado al método reset. Lo podemos usar por ejemplo para lanzar un mensaje de aviso al usuario de que se van a borrar los datos. Su uso pasa por usar una sintaxis del tipo:
<FORM NAME = " form1" ACTION = "/cgi/proceso.cgi" ONRESET = " alert ( ' se van a borrar los datos' ) " >
onClick : este no es un evento típico del objeto form, pero se puede usar con én, y mediante él podemos ejecutar una acción concreta cuando el usuario hace click en cualquier parte del formulario, sin necesidad de que se pulse en un campo; sólo es necesario pinchar en algún lugar del espacio ocupado por el formulario en su totalidad.. Su escritura se debe parecer a:
<FORM NAME = " form1" ACTION = "/cgi/proceso.cgi" ONCLICK = " alert ( ' ha pulsado un campo' ) " >
Además de estos eventos, y al igual que ocurre con onClick, el objeto form también admite los eventos generales ondblClick, onmouseOver, onmouseOut, onkeyPress , etc, pero su uso acarrea más problemas que beneficios, por lo que no se utilizan. Sólo saber que estás ahí y que se pueden usar en casos muy específicos.
Uno de los elementos más usados a la hora de implementar un formulario son las cajas de texto. Estas se definen en HTML mediante la etiqueta:
<INPUT TYPE = " text " NAME = " nombre " VALUE = " valor_por_defecto " SIZE= " tamaño_por_defecto">
El elemento TEXT introduce una caja para que el usuario introduzca un texto, texto que será visible por el mismo en todo momento, el elemento es análogo a este, pero se diferencia en que está concebido para que en él se introduzcan contraseñas, por lo que cuando el usuario escribe algo en su interior este texto se va almacenando dentro, pero en pantalla sólo se muestran asteriscos, ****, por motivos de seguridad. Por último, el elemento HIDDEN es también igual que el TEXT, pero en este caso no aparece en pantalla ni la caja ni su contenido, y el usuario no puede escribir nada en su interior (pero nosotros sí, por defecto o mediante JavaScript). Vamos a explicar las propiedades y métodos de estos tres elementos análogos mediante las del objeto TEXT, teniendo siempre presente que lo que digamos es extensible a los tres. Para más información sobre estos elementos, su sintaxis o propiedades.
Pero así, con el código HTML puro, sólo podemos conseguir que el usuario introduzca un texto en el campo, que será enviado luego al programa del servidor tal y como se haya introducido inicialmente, lo que puede ocasionar bastantes quebraderos de cabeza, ya que el valor introducido puede no ser correcto o no corresponder al formato que nosotros deseemos o necesitemos procesar. Y esto es debido a que HTML no posee ninguna herramienta propia para el tratamiento de estos campos de texto.
Mediante el uso de JavaScript sí que podemos actuar fácilmente sobre los campos de texto y sobre sus propiedades, ya que un elemento de formulario TEXT es también para JavaScript un objeto, que por lo tanto tiene sus propiedades, métodos y eventos, a los que podemos recurrir dinámicamente para cambiar valores, validar las entredas del campo, etc.
La forma de acceder a un campo de texto y a sus propiedades y métodos es la general del objeto form, añadiendo a la escritura el nombre del campo y el de la propiedad a la que deseemos acceder:
* name : es la propiedad más importante del objeto text, ya que nos va a permitir identificar cada campo con un nombre identificador único, identificador que vamos a usar luego para poder referirnos sin ambiguedades a un campo de texto concreto dentro de un formulario concreto de nuestra página y acceder a sus propiedades y métodos. Como en la ruta de acceso al campo de texto hay que anteponer el nombre del formulario al que pertenece, y el nombre de cada formulario debe ser único, no hay ningún problema en que usemos el mismo nombre para diferentes campos de texto de diferentes formularios de la página. Lo que no debemos hacer nunca es usar el mismo nombre para campos del mismo formulario, ya que entonces el motor JavaScript del navegador no va a saber al cuál nos referimos y nos dará un error, expresado generalmente mediante el mensaje de que el objeto llamado no existe.
*
value : esta propiedad define el texto que por defecto va a aparecer inicialmente dentro de la caja de texto. A simple vista puede parecer que poco podemos sacar de acceder mediante JavaScript a esta propiedad, pero un estudio más detallano nos dice que esto no es así, y que las posibilidades de uso son muchas. Lo primero es acceder a la propiedad, y esto se consigue mediante la escritura:
document.[nombre_formulario].[nombre_campo].value
y ?para qué podemos usar esto?. Imaginemos por ejemplo que tenemos un campo de texto en el que inicialmente queremos introducir u texto aclaratorio para que el usuario sepa qué tiene que introducir en el campo, pero que una vez que pinche en el campo este texto desapareca. El código necesario para ello sería:
<HTML>
<HEAD>
</HEAD>
<BODY>
<FORM NAME="datos" ACTION="/jsp/pag_3.jsp" METHOD= "post">
Introduce tu nombre: <INPUT TYPE=" text " NAME=" nombre " VALUE= " sólo mayúsculas "
ONCLICK = "document.forms.datos.nombre.value= '' ">
</FORM>
</BODY>
</HTML>
y con esto le estamos diciendo al navegador que cuando el usuario pinche en el campo el texto inicial se sustituya por un valor vacío.
y también podemos conseguir mediante esta propiedad pasar el valor introducido por el usuario en un campo de texto a otro campo de otro formulario, que puede estar en la misma ventana, en otro frame o en una ventana flotante. Esto nos puede servir por ejemplo para hacer un formulario resumen o para pasar valores a campos ocultos ( HIDDEN ). Un ejemplo de código, para pasar el valor a un formulario de la mima página, sería:
La propiedad value lleva asímismo asociada otra propiedad general de JavaScript, la propiedad length, que nos da la longitud del texto introducido en la caja, es decir, el número de caracteres que el usuario ha introducido. Esta propiedad es muy útil y se utiliza mucho, y con ella podemos por ejemplo hacer que el foco salte de una caja a otra cuando se haya introducido en la primera un número dado de caracteres. Vamos a ver un código que hace esto, saltando el foco al segundo campo cuando en el primero se introducen 5 caracteres:
disabled : esta propiedad bloquea el campo de texto, de tal forma que el texto que contenga el campo se colorea de color grís y no se puede escribir nada nuevo en el campo.
Vamos a ver su sintaxis mediante un ejemplo:
<HTML>
<HEAD>
</HEAD>
<SCRIPT LANGUAGE = " JavaScript " >
function bloquea ( ){
document.forms.form1.campo1.disabled = true;
}
function desbloquea ( ){
document.forms.form1.campo1.disabled = false;
}
</SCRIPT>
</HEAD>
<BODY>
<FORM NAME = " form1" >
<INPUT TYPE = " text " NAME = " campo1 " VALUE = " campo de texto" >
<BR><BR>
<INPUT TYPE = " button " VALUE = " campo disabled " ONCLICK = " bloquea ( ) " >
<INPUT TYPE = " button " VALUE = " campo enabled " ONCLICK = " desbloquea ( ) "
*
* size : que establece la anchura de la caja de texto ( ejemplo de uso abajo, asociado al evento onKeyPress).
Los principales métodos del objeto text son:
* focus() : que sitúa el foco en la caja de texto. Este método se puede usar por ejemplo cuando se realiza una validación de formulario y hay algún dato incorrecto; podemos entonces lanzar un mensaje de alerta al usuario y situar el cursor en el campo incorrecto. El código para ello sería:
select(): este método selecciona el texto contenido en la caja, poniendo todo el contenido de la misma con un fondo azul estandar. Su uso pasa por la sintaxis:
toUpperCase - toLowerCase : estos métodos propios convierten el texto introducido a mayúsculas y a minúsculas respectivamente, y van asociados a la propiedad value de la caja de texto. Vamos a ver el código necesario para pasar a mayúsculas en texto que el usuario introduce en un elemento text:
Por otra parte, el objeto TEXT posee los siguientes eventos:
* onFocus : este evento permite lanzar una acción cuando la caja de texto recibe el foco, es decir, cuando el usuario pincha con el ratón la caja o cuando accede a ella mediante el tabulador del teclado. Un ejemplo de llamada al método sería:
<INPUT TYPE = " text" NAME = " campo1 " ONFOCUS = " alert ( ' foco en la caja ' ) " >
* onBlur : mediante este evento podemos ejecutar una acción dada cuando la caja de texto pierde el foco, bien porque el usuario trás escribir en ella pinche en otra parte de la página o bien cuando accede a otro campo del formulario mediante el tabulador. Su uso pasa por usar una sintaxis del tipo:
<INPUT TYPE = " text" NAME = " campo1 " ONBLUR = " alert ( ' foco fuera de la caja ' ) " >
Vamos a ver un ejemplo de cómo podemos utilizar estos dos eventos. Vamos a crear un formulario con dos cajas de texto, de tal forma que después de escribir en la primera al pasar a la segunda cambiará el texto que hayamos introducido por otro ( evento onBlur ), mientras que la segunda caja se escribirá sóla ( evento onFocus ):
<HTML>
<HEAD>
<SCRIPT LANGUAGE = " JavaScript ">
function pinta1( ){
document.form1.campo1.value = " evento onFocus" ;
}
function pinta2 ( ){
document.form1.campo2.value = " evento onBlur" ;
}
</SCRIPT>
</HEAD><BR><BODY>
<FORM NAME = " form1">
<INPUT TYPE = " text " NAME = " campo1 " ONBLUR = "pinta2 () ">
<INPUT TYPE = " text " NAME = " campo2 " ONFOCUS = " pinta1() ">
</FORM>
</BODY>
</HTML>
# onClick : este evento es aceptado por el objeto text, pero su efecto en este caso es el mismo que el del evento onFocus, por lo que su uso es análogo.
# onChange : evento se lanza cuando el texto que aparece en un campo de texto se cambia por otro diferente. Su escritura se debe parecer a:
<INPUT TYPE = " text" NAME = " nombre" ONCHANGE = " alert ( ' lo que sea' ) " >
si cambiamos el nombre que aparece por defecto en el primer cambio recibiremos un mensaje de alerta.
onMouseOver - onmouseOut: estos dos eventos son aceptados por el objeto text, aunque su buen uso depende de la habilidad del programador, ya que a veces nos puede traer problemas, por ejemplo si lo usamos asociado a un mensaje de alerta, ya que en ese caso nunca podrá el usuario escribir en la caja. Vamos a ver un ejemplo de uso, que además de enseñarnos cómo se deben usar estos eventos nos va a mostrar las dificultades que puede ocasionerle al usuario si no se usan corréctamente. Vamos a colocar dos campos de texto; en el primero va a aparecer un mensaje indicando al usuario que introduzca su nombre, y cuando este ponga el cursor sobre el campo se le indicará que lo introduzca en mayúsculas. En el segundo campo aparecerá un mensaje cuando el usuario quite el ratón del primer campo. Pero si este vuelve a pasra el ratón por el primer campo, el texto que introdujo desaparece. ?Cómo se arregla esto...?. Pensad un poco. El código de nuestro ejemplo será:
<HTML>
<HEAD>
</HEAD>
<BODY>
<FORM NAME = " form1" >
<INPUT TYPE = " text " NAME = " nombre " VALUE = " pon aquí tu nombre "
ONMOUSEOVER = " document.form1.nombre.value = ' usasólo mayúsculas ' "
ONMOUSEOUT = " document.form1.mensaje.value = ' bonito nombre'" ><BR><BR>
<INPUT TYPE = " text " NAME= "mensaje">
</FORM>
</BODY>
</HTML>
onkeyPress : este evento se produce cuando el usuario pulsa una tecla cualquiera. Vamos a ver un ejemplo de uso, en el que vamos a colocar una caja de texto con un ancho inicial (fijamos ek atributo size), pero que vamos a ir modificando cuando el usuario introduzca más texto del que puede contener. El código es:
var n=document.form1.caja1.value.length;
if(n > 4) document.form1.caja1.size=n+1;
}
</script>
</head>
<body bgcolor="#ffffcc">
<form name="form1">
introduce un el texto que quieras:
<input type="text" name="caja1" size="4" onkeypress="valora()">
</form>
</body>
</html>
Nota Importante: Los objetos hidden son un elemento fundamental en muchos formularios, ya que permiten almacenar valores que podemos ir pasando a estos campos y que se utilizan para definir configuraciones del usuario o del propio formulario, todo ello de una forma transparente para el usuario, que en ningún momento es consciente de la existencia de estos campos ocultos. La forma de acceder a ellos y a su propiedad value, la fundamental para esta técnica, es la msima que para acceder a un campo de texto cualquiera.
TU NO PUEDES Escribir nuevos temas en este foro TU NO PUEDES Responder a los temas en este foro TU NO PUEDES Editar tus propios mensajes en este foro TU NO PUEDES Borrar tus propios mensajes en este foro
Todas las fechas y horas son GMT+1. Ahora son las 18:15