Procesamiento de formularios

Autor: J. G. Castellano (fjgc@decsai.ugr.es)

1.- Formularios.

Los formularios nos van a permitir introducir información con el terminal WAP, esa información la vamos a poder procesar posteriormente con WMLScript, lo cual no sirve de mucho, por que la información se queda en el móvil, pero también vamos a poder procesar dicha información mediante CGI, lo cual si nos va a servir, por ejemplo, para tener una base de datos de clientes o para proporcionar un información precisa al terminal WAP como es el caso de un buscador WAP.

Los formularios lo habeis visto en la parte de WML sobre introducción de datos.

2.- Elementos de un formulario.

2.1 fieldset

La etiqueta fieldset nos permite agrupar varios elementos de texto o inputs dentro de una carta. La forma en que agrupemos los elementos puede afectar a la presentación de los mismos en el dispositivo y también en la navegación, ya que el móvil presentará los contenidos en el orden en que se incluyen. Posee el atributo title que es una pequeño título que deberá ser de 5 ó 6 caracteres. Dentro de <fieldset></fieldset> se pueden incluir los siguientes elementos:

  1. <fieldset>
  2. <input>
  3. <select>
  4. Texto
Ejemplo
	<?xml version="1.0"?>
	<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
	<wml>
	<card id="hw" title="Fieldset">
	<p>
	<fieldset title="Usuario">
	Nombre:<input type="text" name="nombre"/>
	<br/>
	Apellido:<input type="text" name="apellido"/>
	<fieldset/>
	<br/>
	<fieldset title="Sexo">
	<select name="sexo">
	<option value="F">Femenino</option>
	<option value="M">Masculino</option>
	</select>
	</fieldset>
	<br/>
	<a href="http://mercurio.ugr.es/cgi-bin/javi/wap/usuarios.cgi?NOMBRE=$(nombre)&amp;APELLIDO=$(apellido)&amp;SEXO=$(sexo)">Continuar</a>
	</p>
	</card>
        </wml>

Probar el ejemplo...

2.2 input

La etiqueta input permite al usuario del terminal WAP introducir texto que luego podemos asignar a una variable. Input puede tener un contenido por defecto. Es una etiqueta autocontenida, es decir, que al final se cierra.

Los atributos más utilizados de esta etiqueta son:

atributo/valores descripción
type="text|password" Indica si veremos los datos que introducimos (text) o no (passwd)
name="variable" Crea una variable y la la rellena con los datos introducidos
title="texto" Etiqueta de presentación del input
accesskey="número" * Asigna la tecla de un número al input, para acceder más rápido
value="valor" Asigan un valor por defecto
size="número" * Ancho, en caracteres, del campo de entrada.
maxlength="número" Número máximo de caracteres que se pueden introducir.
* No todos los móviles lo soportan

2.3 select

La etiqueta select especifica una lista de opciones entre las que el usuario puede elegir una o más. Cada opción se define con la etiqueta option. El contenido de select se presenta en el orden en que lo escribamos. También se puede usar la etiqueta optgroup, pero no las soportan todos los dispositivos. Los atributos más utilizados de esta etiqueta son:
atributo/valores descripción
name="variable" Crea una variable y la la rellena con los datos introducidos
title="texto" Etiqueta de presentación del select
multiple="true|false" Indica si podemos seleccinar más de un elemento de la lista
value="opcion" Indica el valor por defecto
ivalue="número/s" Nos permite indicar más de un elemento por defecto mediante una lista de números separadas por ;
iname="variable" Crea una variable rellenada con los números de ivalue
Ejemplo
	<?xml version="1.0"?>
	<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
	<wml>
	<card id="hw" title="select">
	<p>
	¿A dónde has viajado?
        <br/>
        <select multiple="true" name="pais" iname="i" ivalue="2;3">
	<option value="SriLanka">Sri Lanka</option>
	<option value="Hungria">Hungría</option>
	<option value="Afganistan">Afganistan</option>
	<option value="Mexico">Mexico</option>
	</select>
	<br/>
	La variable pais = $(pais)
	<br/>
	La variable i = $(i)
	<br/>
	</p>
	<do type="accept">
	</card>
        </wml>

Probar el ejemplo...

2.4 postfield

Con esta etiqueta podemos crear una variable y asignarle un valor. Se utiliza para enviar información a un CGI. Los atributos más utilizados de esta etiqueta son:

atributo/valores descripción
name="variable" Crea una variable y la la rellena con los datos introducidos
value="valor" Indica el valor por defecto
Ejemplo
             <?xml version="1.0"?>
             <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">

             <wml>
               <card title="postfield">
                 <p> Ejemplo de postfield</p>
                 <do type="accept">
                   <go method="post" href="http://mercurio.ugr.es/cgi-bin/javi/wap/parametros.cgi">
                     <postfield name="x" value="1"/>
                   </go>
                 </do>
               </card>
             </wml>


Probar el ejemplo...

2.5 Variables y valores por defecto

Con tan solo especificar una serie de variables o valores por defecto en el código WML y un enlace a un CGI podemos mandar información a un CGI, pero hay que tener en cuenta las limitaciones de este método, ya que no nos va a permitir captar información del usuario del terminal WAP, no obstante nos puede servir para declarar variables que funcionarán de forma análoga a los campos ocultos de los formularios HTML.

Ejemplo

	<?xml version="1.0"?>
	<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
	<wml>
	<card id="hw" title="Idioma">
	<p>
	<a href="http://mercurio.ugr.es/cgi-bin/javi/wap/parametros.cgi?idioma=ESP">Castellano</a>
	<a href="http://mercurio.ugr.es/cgi-bin/javi/wap/parametros.cgi?idioma=ING">English</a>
	</p>
	</card>
        </wml>

Probar el ejemplo...

3.- Como pasar parámetros a un CGI

Hay dos formas:

  1. Utilizando las etiquetas postfield y go, como se ha visto en el ejemplo de postfield
  2. Pasando los parámetros directamente en la dirección utilizando la etiqueta a, como se ha visto en el ejemplo de variables o en el ejemplo de fieldset. También se puede hacer, de forma, análoga con <do> mas <go> o con <do> mas <anchor>, añadiendo en la dirección (atributo href) los parámetros.

4.- El atributo method de go.

El atributo method de la etiqueta go nos va a permitir expecificar el modo de envío de los datos del terminal WAP al servidor. Los modos son:

La diferencia entre ambos métodos es que get pasará los datos mediante una cadena de solicitud, por ejemplo:
	parametros.cgi?var1=valor1&var2=valor2.... etc.	
Mientras que el método post es invisible ya que se almacenan los datos en una parte diferente del servidor cuando llega allí. Hay que tener en cuenta que con get podemos ver (y los demás también) las variables que estamos enviando y sus valores, lo cual siempre ayuda a depurar los CGI, pero, en cambio, get tiene un límite de tamaño de 1 Kb, mientras que el método post no.

Hay que tener en cuenta que, si bien, los parámetros en la página WML se especifican como si fuera una cadena del método get, la forma de enviar los datos al servidor depende del método especificado, que es lo que nos interesa a nosotros para hacer la captura de parámetros. Si, para enviar los parámetros se utiliza una etiqueta <a> o <do> más <anchor>, entonces el método será get.

Para determinar, en el propio CGI, el método de paso de parámetros (get o post), se consulta la variable de entorno REQUEST_METHOD que puede ser igual a GET o POST. En Perl esto se hace asi:

#Miramos el método de paso de parámetros al CGI
$metodo=$ENV{"REQUEST_METHOD"};

#Según sea una método u otro nos vamos a un sitio o a otro
if ($metodo eq "GET")
{	#caso de GET
	.....
}
else
{	#caso de POST
	.....
}
En el método get los parámetros se obtienen de la variable de entorno QUERY_STRING, mientras que en el método post se obtienen de la entrada estándar (en Perl de <STDIN>). Un CGI que trate los dos tipos de métodos de paso de parámetros sería el siguiente:
	
#!/usr/bin/perl
print "Content-type: text/vnd.wap.wml\n\n";

#Impimo la cabecera de la pagina WML
print<<"pagina_wap";

        <?xml version="1.0"?>
        <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
        <wml>
        <card id="hw" title="Argumentos">
pagina_wap

#Determinamos el tipo de metodo usado para pasar los argumentos
$metodo=$ENV{"REQUEST_METHOD"};
if ($metodo eq "GET")
{	#Si el metodo es GET los argumentos vienen en $ENV{"QUERY_STYRNG"}
	$argumentos=$ENV{"QUERY_STRING"};
}
else
{  	#Si el metodo es POST los argumentos vienen en la entrada estandar
   	$argumentos=<STDIN>;
}

# Obtengo las variables (divididas por &) y las imprimo
foreach (split(/&/,$argumentos))
{    #Separo la variable y su valor asociado
    ($variable,$valor) = split(/=/, $_);
    #En las cadenas sustituyo el + por espacios
    $valor=~tr/+/ /;
    #Reformateo
    $valor=~s/%([0-9|A-F]{2})/pack(C,hex($1))/eg;

    #Leemos las variables y las imprimo
    print ("<p>$variable=$valor</p>");
}

#Imprimo el metodo usado
print "\n<p>EL metodo usado ha sido $metodo</p>\n";

#Imprimo la cola de la página WML
print<<"pagina_wap2";
	<do type="accept" label="Atras"><prev/></do>
        </card>
        </wml>

pagina_wap2

Ejemplo con los métodos get y post:

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
	<card title="get/post">
                 <p>Ejemplo de get y post.
               	
                 	<!--Ejemplo de get-->
                 	<br/>
	                 <do type="accept" method="get" label="Ej.Get">
	                   <go	href="http://mercurio.ugr.es/cgi-bin/javi/wap/get_post.cgi?param1=a&amp;param2=2">
	                   </go>
	                 </do>
                 	
                 	<br/>
	                 <do type="accept" method="post" label="Ej.Post">
	                   <go	href="http://mercurio.ugr.es/cgi-bin/javi/wap/get_post.cgi">
	    	                   <postfield name="param1" value="1" />
	    	                   <postfield name="param2" value="b" />    	
	                   </go>
	                 </do>
                 </p>
	</card>
</wml>


Probar el ejemplo de get y post...


5.- Ejemplos de procesamiento de datos por un formulario

Utilizaremos el ejemplo visto en fieldset En el CGI se va a capturar los parámetros que le pasa la página wml, y los almacenará en un fichero con información de todos los usuarios que se han introducido. Finalmente el CGI abrirá dicho fichero y mostrará todos los usuarios introducidos.
#!/usr/bin/perl
print "Content-type: text/vnd.wap.wml\n\n";

#Impimo la cabecera de la pagina WML
print<<"pagina_wap";

        <?xml version="1.0"?>
        <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
        <wml>
        <card id="hw" title="Argumentos">
pagina_wap

#Determinamos el tipo de metodo usado para pasar los argumentos
$metodo=$ENV{"REQUEST_METHOD"};
if ($metodo eq "GET")
{    	#Si el metodo es GET los argumentos vienen en $ENV{"QUERY_STYRNG"}
	$argumentos=$ENV{"QUERY_STRING"};
}
else
{  	#Si el metodo es POST los argumentos vienen en la entrada estandar
   	$argumentos=<STDIN>;
}

# Obtengo las variables (divididas por &) y las imprimo
foreach (split(/&/,$argumentos))
{    #Separo la variable y su valor asociado
    ($variable,$valor) = split(/=/, $_);
    #En las cadenas sustituyo el + por espacios
    $valor=~tr/+/ /;
    #Reformateo
    $valor=~s/%([0-9|A-F]{2})/pack(C,hex($1))/eg;

    #Leemos las variables de entrada
    $nombre=$valor if ($variable eq "NOMBRE");
    $apellido=$valor if ($variable eq "APELLIDO");
    $sexo=$valor if ($variable eq "SEXO");
}

#Guardamos el usuario
 if (open (F,">>usuarios.dat") ==1 )
 {	#Escribimos el usuario
	print F "$nombre|$apellido|$sexo\n";
	#cerramos	
	close (F);
 }
 else
 	{print "\n<p>ERROR: No se puede escribir en el fichero de usuarios.</p>";}


#Leemos todos los usuarios y las mostramos por pantalla
 #Abrimos el fichero de usuarios
 if (open(F,"usuarios.dat")==1)
 {
 	#Leemos las opiniones y las mostramos por pantalla
	 while(<F>)
	 {    	($user,$apell,$sex) = split(/\|/,$_);
	 	print "<p> Usuario=$user $apell.<br/>Sexo=$sex</p>";
	 }
	 #Cerramos el fichero de usuarios
	 close(F);
 }
 else
 	{print "\n<p>ERROR: No se puede leer del fichero de usuarios.</p>";}


#Imprimo la cola de la página WML
print<<"pagina_wap2";
	<do type="accept" label="Atras"><prev/></do>
        </card>
        </wml>

pagina_wap2
Probar el ejemplo...


6.- Ejercicios

Libro de visitas en WML

Ejercicio
Se trata ahora de hacer lo mismo que en el anterior ejemplo, pero en la página se debe introducir una campo de nombre y otro campo donde donde se exprese la opinión acerca del sitio donde están las páginas.

Probar el ejemplo...
Truco:Para los que no sepan Perl(o no se acuerden) para hacerlo aqui tienen el código que escribe y lee de un fichero que hace las veces de libro de visitas:
	.....
#Guardamos el usuario y la opinion
 if (open (F,">>visitas.dat") ==1 )
 {	#Escribimos las opinion del usuario
	print F "$usuario=$opinion\n";
	#cerramos	
	close (F);
 }
 else
 	{print "\n<p>ERROR: No se puede escribir en el libro de visitas.</p>";}

#Leemos todas las opiniones y las mostramos por pantalla
 #Abrimos el libro de visistas
 if (open(F,"visitas.dat")==1)
 {
 	#Leemos las opiniones y las mostramos por pantalla
	 while(<F>)
	 {    	($uno,$opina) = split(/=/,$_);
	 	print "<p> $uno: $opina</p>";
	 }
	 #Cerramos el libro de visitas
	 close(F);
 }
 else
 	{print "\n<p>ERROR: No se puede leer del libro de visitas.</p>";}
	
	.....


 
Grupo GeNeura. http://geneura.ugr.es
Departamento de Arquitectura y Tecnología de los Computadores.
Universidad de Granada