Recoger campos de formulario complejos en ASP

  • 31 de mayo de 2002
  • Valoración:
  • 16 Comentarios
  • Scripts en ASP
Explicamos como recoger campos de formulario en los que recibimos más de un valor por campo.
No debería significar un problema recoger los campos de formulario corrientes, como campos de texto, botones de radio, textareas, etc, donde sólo se envía un dato vinculado a dicho campo campo. Se hace con la método form del objeto request, indicando entre paréntesis el nombre del campo que queremos recoger.

mi_variable = request.from("nombre_campo")

Para el que esto le resulte nuevo, podemos encontrar en el Manual de ASP un capítulo donde se detalla el proceso de recoger datos del formulario. Nosotros en este artículo vamos a tratar de explicar un método para recoger datos un poco más complejos, donde nos pueden enviar varios valores dentro de un mismo campo de formulario. En concreto vamos a tratar de extraer los datos de un campo de formulario "Select múltiple" que se consigue con las siguientes etiquetas HTML:

<select name="equipo" multiple>
<option value="Madrid">Madrid
<option value="Barcelona">Barcelona
<option value="Valencia">Valencia
<option value="Bilbao">Bilbao
<option value="Sevilla">Sevilla
<option value="ATMadrid">At. Madrid
<option value="Cadiz">Cadiz
<option value="Dep. Coruña">Dep. Coruña
<option value="Santander">Santander
</select>


Hemos colocado un select normal que tiene el atributo múltiple, que vemos que no se iguala a nada, simplemente se coloca si queremos que el usuario pueda seleccionar varias opciones. Para ello debería seleccionar una de las opciones y con el la tecla de Control (Ctrl) o mayúsculas (La flechita hacia arriba) seleccionar otra opción. Si se utiliza la tecla de Control se seleccionan las dos opciones, la que había y la nueva. I se utiliza mayúsculas se seleccionarían todas las opciones entre la primera y la última. Podemos practicar a seleccionar varias opciones, para el que lo desee, con el campo de abajo.


Cómo llegan los datos

Cuando recibimos este campo de formulario nos llegan todos los valores que un usuario haya seleccionado, separados por comas. Así, un valor posible que se puede recibir por el formulario sería el siguiente:

Madrid, Barcelona, Valencia, ATMadrid, Dep. Coruña

Este valor lo obtenemos utilizando el objeto request de ASP, tal como comentábamos antes. Para acceder entonces a ese dato escibiríamos.

request.form("equipo")

El método reques.form en este caso devuelve, como indicábamos, todos los equipos seleccionados separados por comas. De manera adicional, podemos tratar el valor devuelto como una colección, que es una estructura de datos especial, parecida a los arrays, que se recorren fácilmente con un bucle FOR EACH.

Referencia: Tenemos un taller de ASP en el que hacemos un par de ejemplos del bucle FOR EACH para recorrer arrays y colecciones.

En algún caso puede interesarnos volcar la información de esa colección a un array para tratar luego los equipos en otros procesos. Como práctica también puede ser útil ver como se haría y de paso, conocemos un poco mejor el bucle FOR EACH.

Construir el array

Nuestro ejercicio requiere un array que tenga un número indeterminado de casillas, que depende del número de valores que recibamos desde el campo <select> del formulario. Si queremos hacer esto bien vamos a necesitar un array dinámico, al que iremos asignando posiciones según lo necesitemos. En el Manual de Visual Basic Script podemos encontrar la explicación sobre cómo tratar arrays dinámicos.

dim equipos()
redim equipos(0)

Así creamos el array y le indicamos que vamos a utilizar como índice máximo el cero, que corresponde con una casilla, equipos(0).

Script para meter los datos en un array

Vamos a hacer un script que se encargue de rellenar el array con todos los valores del campo. Dicho script recorre la lista de valores que llegan del formulario y los introduce en el array, a la vez que va aumentando en una casilla el espacio del array antes de añadir un nuevo elemento.

Dim equipos(), I
I = 0
For Each Valor In Request.Form("equipo")
    Redim Preserve equipos(I)
    equipos(I) = Valor
    I = I + 1
Next


Empezamos el script declarando el array (sin definir sus casillas, para poder redimensionarlo dinámicamente) y una varible para llevar la cuenta de los valores introducidos, que inicializamos a cero en la siguiente línea.

El bucle FOR EACH recorre cada una de las posiciones de la colección Request.Form("equipo") y en cada iteración introduce en una variable, en este caso llamada Valor, el contenido de la posición actual. Una vez dentro del bucle se redimensiona el array preservando su contenido previo (redim preserve) para que contenga las posiciones necesarias para almacenar los valores que vamos extrayendo de la colección. Dicho de otro modo, en cada iteración creamos una nueva posición (guardando todas las posiciones anteriores) e introducimos en la posición creada el contenido de la variable Valor, que guardaba la posición actual de la colección. Por último incrementamos en uno el número de posiciones que debe contener el array, para utilizarlo si volvemos a pasar por el bucle.

Nota: Podíamos haber creado un array utilizando la función split, incorporada en VBScript. Dicha función recibe una cadena y un separador y devuelve un array donde en cada casilla se ha introducido una sub-cadena creada al romper por cada separador.

De modo que, a partir del request.form("equipo") (que es también una cadena donde cada valor aparece separado por una coma), aplicando la función Split e indicando que el separador es el caracter coma (,), obtendremos el array deseado.

equipos = Split(request.form("equipo"),",")

Este método es muy rápido y simple, pero podría fallar si uno de los valres del select contiene una coma, tal como apuntan algunos colaboradores con sus comentarios al artículo.

Espero que con lo dicho hasta ahora hayamos podido encontrar sentido al ejercicio y resulte válido como práctica de VBScript y la tecnología ASP. Podemos ver el ejemplo en marcha para examinar su funcionamiento.

Además, podemos descargar en un zip los fuentes que hemos utilizado con ASP para este ejercicio, por si los queremos tener y probar en nuestro computador.

Créditos y agradecimientos

Este reportaje ha sido mejorado gracias a los comentarios, investigaciones y correcciones de las siguientes personas:

Sergio Flores: flaco@lamatufia.com.ar. Agradecimientos especiales a este compañero, que indico el script para recorrer la colección

Antonio Guerrero agnotario@eresmas.com. Nos apuntó la solución con la función split.

César Nieto cesarnieto@terra.es. También nos recomendó utilizar split.

Aston aston@maestrosdelweb.com. Que nos propuso la solución con Split y también un recorrido de colecciones.

Al pie del artículo se conservan todos los comentarios enviados por los anteriores compañeros, y otros que podrán ir incorporándose. Muchas gracias a todos.

Comentarios

Miguel Angel Alvarez

31/5/2002
Investigando un poco sobre este caso, he comprobado que los distintos valores del campo del formulario también se pueden recoger por separado indicando el índice del valor a tomar. De esta manera:

request.form("campo")(1)

Así recogeríamos el valore venido en primer lugar. Si queremos recoger el valor del segundo lugar lo haríamos igual, indicando con un 2 el índice de la posición a recoger.

request.form("campo")(2)

Lo que no veo claro es cómo hayar el número de posiciones del supuesto array. Pues,a unque lo podamos acceder con índices como un array, en realidad no lo es. Por lo tanto uBound() no sirve para hallar la solución. Lo que se me ha ocurrido, que pienso que sí funcionaría bien es contar el número de comas que tenga request.form("campo")... entonces el número de valores que nos llegan sería ese número de comas + 1.

Sergio Flores

01/6/2002
Queridos amigos de Desarrollo Web:

Si lo que ustedes quieren es almacenar en un array todos los valores, no es necesario semejante funcion ni menos saber el mayor número del índice.
No se puede utilizar UBound() ya que no es un array, pero como es una colección es más fácil todavía:

<%
Dim MisDatos(), I
I = 0
For Each Valor In Request.Form("CampoMultiple")
       Redim Preserve MisDatos(I)
       MisDatos(I) = Valor
       I = I + 1
Next
%>

Espero que les haya servido de algo y hasta pronto.
Muy bueno el sitio!!
Un abrazo desde La Rioja, Argentina.

Antonio Guerrero

03/6/2002
Una forma alternativa para obtener los datos de una select multiple es utilizar la funcion Split que lo soporta VBScript

Ejemplo:

Dim i
Dim v
Dim vMatriz
v = Request("miSelect")

if v <> "" then
    vMatriz = Split(v,",")
end if

A partir de aquí, se puede acceder a los valores seleccionados de la select en la matriz vMatriz

for i = lbound(vMatriz) to ubound(vMatriz)
   'tratar vMatriz(i)
next

Nota: Funciona igual si sólo se selecciona un elemento

Antonio Guerrero

03/6/2002
En respuesta a la duda de Miguel Angel decir que el numero de elementos se puede obtener con:

request.form("campo").count

Saludos

César Nieto

03/6/2002
Veo más práctico utilizar la función Split.

miarray=Split(mitexto,",")

Me crea un array con los elementos que hay separados por el carácter que yo le diga, en este caso la coma.

Aston

03/6/2002
Hola amigos:

En cualquier caso, podemos facilitarnos la tarea de meter en un array (matriz o arreglo) los valores recogidos de un Select múltiple ¡con una sola línea!

aEquipos = Split(Request.Form("Equipos"), ",")

¡Ya está, ya hemos llenado el array!

Esto devuelve:

aEquipos(0) = "Madrid" aEquipos(1) = "Barcelona" aEquipos(2) = "Valencia" aEquipos(3) = "ATMadrid" aEquipos(4) = "Dep. Coruña"

Espero que sirva de ayuda.

Aston - http://www.laventanita.net

Aston

03/6/2002
Hola de nuevo:

Investigando un poco sobre el problema que plantea nuestro amigo Miguel Angel Alvarez, saber cuántos elementos tendría nuestro supuesto array, la mejor opción pasa por tratarlo como una colección para recorrerlo después con un sencillo bucle For Each... Next con lo que de nuevo solucionaríamos el problema en pocas líneas:

Ejemplo:

<%
For Each n in Request.Form("Delegaciones")
  Response.Write n & "<br>"
Next
%>

<HTML>
<HEAD>
</HEAD>
<BODY>
<form method="post" name="Deleg" action="Multi.asp">
<SELECT NAME="Delegaciones" SIZE="7" multiple>
<option value='Andalucía'>Andalucía</option><option value='Cataluña'>Cataluña</option><option value='Centro I'>Centro I</option><option value='Centro II'>Centro II</option><option value='Levante'>Levante</option>
</SELECT><br>
<INPUT type=submit value=Submit name=submit1>
</form>
</BODY>
</HTML>

Aston - http://www.laventanita.net

Sergio Flores

04/6/2002
Hola de vuelta.

He visto que han publicado otros lectores soluciones con la función de expresiones Split, la cual guarda en un vector o array todos los valores separados por un determinado delimitador (en este caso la coma ",").

El problema que existe utilizando esta funcion se presenta que al mostrar un select multiple con valores como por ejemplo "Gimenez, Benjamin", "Alanis, Lucas", etc. éste devuelve datos erroneos, en este ejemplo devolveria en el array(0) = "Gimenez", en array(1) = "Benjamin", en array(2) = "Alanis" y en array(3) = "Lucas" y no array(0) = "Gimenez, Benjamin" y array(1) = "Alanis, Lucas" como deberia ser. Esto se soluciona utilizando For Each como lo expliqué anteriormente.

Hasta pronto!

Walter Portocarrero

17/6/2002
Hola, simplemente queria agregar una cosilla al ejemplo que utilizan para recojer varios valores de un control select:

Una forma que yo encontre para poder recojer varios valores seleccionados de un select fue de la siguiente manera:

for i=1 to request.form("sel_Rev").count
    usu = request.form("sel_Rev")(i)
next

que es equivalente al FOR EACH, y que es basicamente la misma idéa.

Espero que esta pequeña colaboración pueda servir a quienes recien empiezan en este maravilloso mundo que es el desarrollo de aplicaciones web.
Saludos

Pablo Guillenea

27/3/2003
Es un gusto opinar del tema, dado que hasta unas horas atrás tenía dicho problema... gracias a su ayuda encontre mi propia solución haciendo una mezcla de todo; aqui va mi solución.

<%
dim cadena
dim vectror
dim i

cadena=request.querystring("tabla")

vector=split(cadena, ",")%>
<table>
<%for i=0 to ubound(vector)
%>

    <tr>
       <td>
       <%response.Write(vector(i))%>
       </td>
    </tr>
<%
next%>

espero que les guste y le encuentren utilidad;
Saludos y muchas gracias...

Hugo

21/4/2003
Yo siempre utilizo este método:

<%idARR = split(id,",")
for i=0 to ubound(idARR)%>

<%=idARR(i)%><br>

<%next%>

Pedro

25/9/2003
Tengo un gran problema, ya que yo creo una tabla y para cada fila de mis registros creo un CheckBox y quisiera saber como hacerle cuando varias casillas sean seleccionadas estas indiquen que estos registros deben ser borrados.

Alejandro

11/11/2003
Este es unejemplo para ver lo ke nos esta regresando el objeto de la forma....podemos tratar los datos de igual manera para insertarlos en una base de datos. par a hacer una insercion multiple tantas veces como se seleccionen opciones. espero les sea util este ejemplo.hasta pronto for i=1 to request.Form("turnado").count response.Write(request.Form("turnado").item(i)&",") next

Malak

07/10/2007
Gracias por esta información, me ha sido de mucha ayuda en mi caso que necesitaba modificar en una base de datos los registros seleccionados por el usuario mediante checkbox. Ya habia probado muchas formas y esta fue la que me funcionó. Mil gracias!!

Moninamoon

02/7/2010
AYUDA
Necesito modificar algunos registros de una base de datos en ACCESS, según selección previa que se realiza mediante un <INPUT TYPE=CHECKBOX NAME=ASIGNA VALUE=<%=RS("ID_SOL")%>, sin embargo, no ha sido posible que me actualice únicamente los registros necesarios, si me pueden ayudar se los agradecería enormemente:

for i=1 to request.form("ASIGNA").count
sql="UPDATE SOLICITUDES SET COD_ESTADO='EST002', USUARIO_GESTION='"&Request.Form("GESTION")&"' WHERE CInt(Id_SOL)='"&Request.Form("ASIGNA")(i)&"'"
Set RS = conexion.Execute (sql)
Next

Rafael Valle

18/8/2013
Los datos de distintos campos de un mismo registro
Yo tengo un problemilla, que supongo que tendrá más de uno.
con un checkbox selecciono los registros que quiero modificar, y para eso el Lbound to Ubound me viene genial. Pero si además quiero añadir los datos de un segundo campo, por ejemplo:
Tengo desplegado de mi BD las facturas pendiente de pago y son 25. Selecciono la 3 y 5 e introduzco la cantidad 100 y 50 Pues bien, al recoger los datos, el campo chekbox funciona (me recoge el IdFactura), pero el campo Pagado, me recoge los datos de los 25 registros

Compartir