Formularios Dinámicos


JavaScript / AjaxLos Formularios Dinámicos son aquellos que se pueden ir generando, mostrando o escondiendo, dependiendo de las opciones que se seleccionen previo al envío del formulario. Dando de esta forma la capacidad de interactuar con el usuario, ajustándose a filtros o necesidades especificas de la operación misma.

Nota: Antes de continuar quiero recomendar unas funciones JavaScript que automatizan y simplifican el manejo de lineas, explicado en un artículo mas reciente que el presente.

Más información en Formularios Dinámicos 2

En este artículo quiero hablar sobre como generar dinámicamente lineas de captura. Aplicable por ejemplo, a un sistema de facturación o quizá a una de pedidos, su aplicación puede ser extensa y cabe mencionar que es más que interesante.

El ejemplo en el cual trabajaré es por demás sencillo, la idea es poder agregar uno y más lineas de captura (un "input"), con la capacidad de borrarlas como se puede ver en el siguiente ejemplo pulsando sobre "Añadir Linea +":

Añadir Linea +



Bonito ¿verdad?, primero generamos el formulario HTML.

<form method="POST">
  <a href="javascript:addLine();">Añadir Linea +</a><br>
  <div id="myDiv"></div>
  <input type="submit">
</form>

Como podemos ver, el formulario se compone de un LINK, un DIV llamado "myDiv" y un botón de SUBMIT. En el "href" del link, podemos ver que se llama a una función Javascript llamada "addLine()", que es la que se ve a continuación:

  // Variable de conteo de "Divs"
  var count = 0;

  // Funcion que agrega una nueva linea
  function addLine(){

    // Se agrega un numero al conteo
    count += 1;

    // Div donde se agregara la nueva linea
    var content = document.getElementById('myDiv');

    // Se crea un nuevo "DIV" que se agregara a content
    var divIdName = 'my' + count + 'Div';
    var newDiv = document.createElement('div');
    newDiv.setAttribute('id', divIdName);

    // Se crea un nuevo "INPUT"
    var newInput = document.createElement('input');
    newInput.type = 'text';
    newInput.size = '10';
    newInput.name = 'myInput[]';

    // Se crea un Link para poder borrar la linea
    var newDelete = document.createElement('a');
    newDelete.href = 'javascript:delLine("' + divIdName + '")';
    newDelete.innerHTML = 'Borrar Linea';

    // Se agrega el "INPUT" y el link al "DIV"
    newDiv.appendChild(newInput);
    newDiv.appendChild(newDelete);
    content.appendChild(newDiv);
  }

Esta función no es muy difícil de entender, se crea un "DIV" con dos elementos, un "INPUT" de texto y un "A" link con el cual podemos borrar cada una de las lineas por separado, aquí debemos tomar atención a dos partes importantes:

newInput.name = 'myInput[]';

El nombre del "INPUT" es "myInput[]" el cual tiene al final unos corchetes, esto es debido a que un campo no puede tener el mismo nombre dentro de un formulario ya que los valores se re-escribirían. Con este truco lo que hacemos es enviar todos los campos generados como un arreglo que puede ser manejado de forma mas simple. Por ejemplo en, PHP recibimos lo siguiente

Array
(
    [myInput] => Array
        (
            [0] => Linea 1
            [1] => Linea 2
            [2] => Linea 3
            [3] => Linea 4
            [4] => Linea 5
        )

)

Lo único que nos falta es el borrado de las lineas, que se realiza con el llamado a otra función declarada en la siguiente linea:

newDelete.href = 'javascript:delLine("' + divIdName + '")';

La llamada es a la función "delLine()", que es la que pongo a continuación:

  // Se borra la linea solicitada
  function delLine(div){
    var content = document.getElementById('myDiv');
    var remove = document.getElementById(div);
    content.removeChild(remove);
  }

Ya con esta base podemos generar lineas mas complejas, con varios campos de captura, seleccionables, textos, etc.

Como siempre, espero que este artículo sea de utilidad y dejo el código fuente para ser descargado desde el siguiente link.

AdjuntoTamaño
directorios_dinamicos.zip960 bytes



Imagen de Anónimo

es maravilloso lo de los formularios dinamicos eso lo que justo estaba buscando. i'll try it .

thanks nexus..

en otro contexto y refieriendose a php y el MVC nos podrias recomendar algo para empezar en la incursion de MVC he leido un poquillo de symfoni que? puedes recomendar pa los novatones como yo.

gracias

Imagen de nexus
Con respecto al MVC yo lo único que he probado es CakePHP y la verdad quedé fascinado, es lo mejor que he visto y probado en muchísimo tiempo, el cual te recomiendo ampliamente.

Saludos
Imagen de Anónimo

Hola, estoy intentando implementar esta forma de generar campos dinámicamente en una web que estoy desarrollando y me topo con la siguiente duda:

Al ver el código fuente de la página una vez generados algunos campos dinámicamente, el código generado no aparece y por lo tanto si envío el formulario el contenido de dichos campos tampoco se envía.

Sabeis como puedo solucionar esto??

Un saludo

Imagen de nexus
Hola

Te comento que aunque en tu HTML fuente no veas los campos generados, efectivamente ahí están, en navegadores como FireFox si seleccionas un área donde existan formularios dinámicos y le das en "Ver código fuente seleccionado" y ahí si podrás ver la generación del HTML.

Sin embargo tu problema es diferente, es probable que donde lo estés generando, no sea dentro de un tag "form"

Tengo un ejemplo en linea y puedes revisar el código fuente.

Saludos
Imagen de Anónimo

OK, pero..

entonces si yo hago u envió vía POST a otra página que procese los datos, lo tendre que llamar así no?

$_POST[myImput][0]

Si es así algun fqallo tengo porque las variables me llegan vacias.

Imagen de nexus
Por que no intentas revisar todas las variables enviadas y como las puedes capturar por medio de print_r($_RQUEST); de esta forma verás si llega o no llegan tus variables.

Saludos
Imagen de Anónimo
Hola, ante todo muchas gracias por el tutorial.

Yo he desarrollado algo parecido y me ha surgido un problema que me ha traido hasta aqui. El problema es que cuando esa estructura de formulario dinámico se pone en una tabla, dependiendo del lugar donde se ponga el 'div' que va a contener los campos dinamicos, en Firefox deja de funcionar y no envia los datos. Me gustaria saber si te has encontrado con ese problema y si has encontrado alguna solución.

el codigo seria algo así:

tabla
fila
form
fin fila

fila
enlace y div: myDiv
fin fila

fila
boton envio
fin fila

fila
fin form
fin fila

fin tabla

El problema creo que está en que firefox cambia la posicion del cierre del form, pero no se como resolverlo.

Un saludo y gracias
Imagen de Anónimo

como recivo los campos myinput[] en php en el caso que necesita mas campos ingresar myinput2[], myinpu3[], etc.(ya los cree y me funcionan en capa cliente-javascript))

Imagen de nexus

Tengo un ejemplo en linea y puedes revisar el código fuente.

Saludos

Imagen de Anónimo

como valido al añadir 1 linea que el usuario haya ingresado 1 valor en la linea anterior

Imagen de nexus

No he encontrado una forma fácil o por lo menos directa, así que lo que yo hago es lo siguiente:

var findInputs = myDiv.getElementsByTagName('input');
for (var i = 0; i < findInputs.length; i++){
   if (findInputs[i].name == 'myInput[]'){
      alert(findInputs[i].value);
   }
}

Primero buscamos todos los "input" dentro del div "myDiv", después los vamos recorriendo y los que se llamen "myInput[]" los podemos verificar.

Espero te sirva. Saludos.

Imagen de Anónimo

como se hace el autocompletar en estos input dinamicos

Imagen de nexus

Eso ya es otra cosa, para lograr hacer autocompletado deberás usar alguna buena librería que use Ajax para lograrlo.

Te puedo recomendar uno que uso mucho: Ajax dynamic List

Saludos

Imagen de Anónimo

la libreria que me recomendaste no me funciono podrias aclararme un poco sobre como funciona.Desde ya muchas gracias.
COn la soga al cuello en la pega me despido
chau

Imagen de nexus

No te funciona?? que raro, funciona perfectísimo, a ver, preguntas:

  • Creaste tu base de datos en MySQL?
  • Cambiaste los datos de conexión a la Base de Datos de los archivos *.php?
  • Estas detrás de un servidor con soporte para PHP y MySQL?
  • Corriste el archivo "create-countries.php" para llenar la base de datos y efectivamente tienes tu tabla con todos los registros?

Si hiciste todos esos pasos estoy seguro que "ajax-dynamic-list.html" te debe funcionar perfectamente bien.

Saludos

Imagen de nanda
Hola.... excelente tu script =) sabes modifique tu codigo para hacer 2 funcione, es decir addLine y addLine2, pero los 2 arreglos que crea
newInput.name = 'myInput[]';
newInput.name = 'myInput2[]';no toman sus respectivos valores...
<table>
<tr>
<td>
<div id ="a">
<input type="text" name="myInput[]" size="10">
</div>
</td>
<td>
<div id ="b">
<input type="text" name="myInput2[]" size="10">
</div>
</td>
</tr>
</table>
sera necesario hacer 2 divs?? sera por eso el error? bye
Imagen de nexus

No deberías de tener ningún problema, de hecho yo también lo he hecho, solo debes de revisar que en tu segunda función cambies las siguientes lineas:

// Div donde se agregara la nueva linea
var content = document.getElementById('myDiv');

// Se crea un nuevo "DIV" que se agregara a content
var divIdName = 'my' + count + 'Div';

newInput.name = 'myInput[]';

A por ejemplo "myDiv2" de la siguiente forma:

// Div donde se agregara la nueva linea
var content = document.getElementById('myDiv2');

// Se crea un nuevo "DIV" que se agregara a content
var divIdName = 'my' + count + 'Div2';

newInput.name = 'myInput2[]';

Ya con eso deberías de tener lista tu segunda función

Imagen de Anónimo

si en uno de los input quiero por ejemplo digitar
aspirina, ¿ como puedo asociar la descripcion al codigo de lo digitado(aspirina)para guardar el codigo de este? o ¿tendria que crear un objeto SELECT en vez de INPUT como en el html ?. desde ya muchas gracias.

Imagen de nexus

Por lo que comentas te sería mucho más efectivo un select, si es que las opciones son pocas, en caso de que sean gran cantidad de datos, volveré a recomendar un Listado Dinámico que uso para mis desarrollos:

Ajax dynamic List

Sin embargo eso ya queda fuera del tema de este artículo que es el de los formularios dinámicos.

Imagen de Anónimo

como puedo poner un objeto select con 2 opciones para seleccionar al lado del input en vuestro codigo que es generado dinamicamente.desde ya muchas gracias

Imagen de nexus

Es relativamente fácil, solo es necesario agregar un código similar al siguiente:

var newSelect = document.createElement('select');
newSelect.name = 'mySelect[]';
var myOption1 = new Option("Si", "Si");
var myOption2 = new Option("No", "No");
newSelect.appendChild(myOption1);
newSelect.appendChild(myOption2);

Y al final no olvidar de poner:

newDiv.appendChild(newSelect);

Y eso es todo.

Saludos

Imagen de Anónimo

aprovecho de corregir tu codigo
para que aparescan la etiquetas del select

var newselect = document.createElement('select'); 
var op1 = document.createElement('option');
var op2 = document.createElement('option');
op1.value = "A";
op2.value = "D";
var txt1 = document.createTextNode('Aspirina     ');
var txt2 = document.createTextNode('Dipirona     ');
op1.appendChild(txt1);
op2.appendChild(txt2);
newselect.appendChild(op1);
newselect.appendChild(op2);
newselect.name = 'myselect[]';

Imagen de Anónimo

$conexion=mysql_connect('localhost', 'root', 'coyote'); 
mysql_select_db('sam');
$query = "SELECT * FROM productos ORDER BY codigo ASC";
$results=mysql_query($query) or die(mysql_error()); 
var sel = document.createElement("SELECT"); 
sel.setAttribute("size","1"); 
sel.setAttribute("name","sel" + count); 

while ($rows= odbc_fetch_array($results)) {
extract($rows); 
echo "opcioncur = document.createElement('OPTION');"; 
echo "opcioncur.innerHTML = '".$descripcion."';"; 
echo "opcioncur.value = '".$codigo."';"; 
echo "sel.appendChild(opcioncur);"; 
}

Imagen de Anónimo

Hola jefe. Gracias a tu codigo nos has salvado de una gorda. Estabamos al borde del precipicio y con un pie fuera de la empresa y tu codigo nos ha reportado un aumento de sueldo. Gracias por todo!!

Imagen de nexus

Que bueno haber podido ayudar, y eso que no he posteado la "nueva" forma de hacer formularios dinámicos sin tanto código JavaScript.

La idea es mucho más simple, se toma todo el contenido de un "div" oculto y se "endosa" (append) al formulario. Esto nos permite trabajar con lineas de datos grandes, con varios "selects", o quizá funciones enlazadas.

Si tengo chance la posteo mañana.

Saludos

Imagen de Anónimo

¿ como puedo pasar los array a traves del parametro url de un window.open.?
Desde Ya gracias
Edgar

var STR_Medicamento=document.getElementById("myselect").value;
var STR_Unidad=document.getElementById("myselect1").value;
var STR_Dosis=document.getElementById("myInput2").value;
	
URL="form_receta_ambulatoria.php?STR_Medicamento="+STR_Medicamento+"&STR_Unidad="+STR_Unidad+"&STR_Dosis="+STR_Dosis+"&STR_Cada="+STR_Cada";
	
opciones='"'+' width='+800+',height='+400+',menubar=no,scrollbars=yes,top='+top+',left='+left+''+'"';
	window.open(URL,'',opciones);

Este codigo no me funciono.

lo que sucede que yo llamo a una ventana window.open con la vista previa de la receta y le quiero pasar los valores del array con los valores ingresados por el usuario con los objetos que creo dinamicamente con java(select,input). y luego abro cuadro de las impresora para que el usuario elija la impresora.
y no he podido pasar los array(con el detalle)

Imagen de nexus
Me parece adecuada tu forma de concatenar el URL, quizá el problema este en el ID o en el nombre, por ejemplo, si tienes algo así:

<form name="formulario">
  <select name="SelectMedicamento">
    <option value="1">Opcion 1</option>
    <option value="2">Opcion 2</option>
  </select>
</form>

Es muy fácil acceder a el de la siguiente forma:

var Medicamento = document.formulario.SelectMedicamento.value;

En cambio, si el caso es como el siguiente:

<form name="formulario">
  <select id="IDMedicamento">
    <option value="1">Opcion 1</option>
    <option value="2">Opcion 2</option>
  </select>
</form>

Entonces si debes de acceder a ella por medio de:

var Medicamento = document.getElementById("IDMedicamento").value;

Favor de notar que en uno se ocupa "name" y en otro se ocupa "id" en el select, y según la lógica que planetas lo concatenas en tu URL para el envío por GET de la siguiente forma:

var URL = "form_receta_ambulatoria.php?Medicamento=" + Medicamento;

Ya por último, recibes tu variable facilmente en PHP (si es lo que usas) de la siguiente forma:

<?php
  echo $_GET['Medicamento'];
?>

Saludos
Imagen de Anónimo

gracias nexus pero en mi codigo el myselect, myselect1 y myInput2 son arrays.
yo cada vez que agrego un detalle(1 medicamento)myselect[0],myselect1[0],myInput2[0]
para el segundo seria myselect[1],myselect1[1],myInput2[1],etc
Los array si los paso a un listado.php me funciona bien.Pero yo quiero la sutileza de pasarlos con url en windows open por que quiero
imprimirlo en la mitad de una hoja.

Imagen de nexus
Ya te entendí!!!

Ok, La tarea no es fácil, vas a tener que recorrer todos los valores, mas o menos así:

var myVars = "";
var findInputs = myDiv.getElementsByTagName('input');
for (var i = 0; i < findInputs.length; i++){
   if (findInputs[i].name == 'myselec[]'){
      if (myVars == ""){ myVars += findInputs[i].value; }
      else { myVars += "|"+findInputs[i].value; }
   }
}

Se esto te va a armar una cadena del tipo "var1|otronombre|ultimo" que puedes volver a convertir a array desde PHP con "explode('|', $var);"
Imagen de Anónimo

funciono perfecto con select e Input.
ahora a maquillar el programa y el listado no mas.

Imagen de Anónimo

hola, cuando cambio el valor de size a 3, por ejemplo, me sigue saliendo siempre del mismo tamaño...

Imagen de Anónimo

Hola, y muchas gracias por tu ayuda de antemano.

Pues eso, que desde el firefox todo funciona correctamente, pero desde el IE no me reconoce los nuevos campos creados dinámicamente. Me dice que el objeto (el campo creado dinámicamente) es nulo o no existe.

Puedes echarme una mano? Gracias.

Imagen de nexus

Hola

Podrías revisar si este ejemplo te sirve en MSIE6?

http://demos.developarts.com/pruebas/formularios/directorios_dinamicos.php

Saludos

Imagen de Anónimo

Hola,
el problema es que cuando creo dinámicamente una serie de líneas, e introduzco valores en esos campos dinámicos, después, al intentar mandar por mail el formulario al que pertenecen, el IE6 me dice que dichos campos dinámicos no existen. Sin embargo, el Firefox sí que los reconoce y los añade al correo generado, junto con el resto de campos estáticos del formulario.

Ves alguna forma de arreglarlo? Muchas gracias, de nuevo.

Imagen de nexus

Por eso te pregunto si el ejemplo anterior te sirve en MSIE6. Si en donde dice respuesta se encuentran todos los valores entonces quiere decir que si funciona, y te recomiendo que le des una vuelta a otro artículo que tengo llamado "Formularios Dinámicos 2" que estoy seguro te funcionará mucho más que este.

Saludos

Enviar un comentario nuevo

  • Etiquetas HTML permitidas: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <pre>
  • Saltos automáticos de líneas y de párrafos.
Más información sobre opciones de formato

Captcha Image: you will need to recognize the text in it.
Igrese las letras que puede ver en la imagen superior