Php,Javascript – Formularios con campos dinámicos.

Una situación que se nos presenta cuando trabajamos con sitios web es la de crear campos de manera dinámica. En esta breve entrada explicaré como pueden crearse campos dinámicos en una página HTML aprovechando Javascript.

Supongamos el siguiente escenario:  Nos solicitan una página para la captura de artículos con la particularidad de que el usuario pueda agregar tantos como desee. La finalidad es claro: acelerar la captura.

Comenzaremos agregando un formulario que incluirá un enlace para permitir que el usuario vaya agregando los campos que requiera:

<form id="formdinamico" name="formdinamico" action="prueba.php">

   <table border="0" width="100%">   
      <tr>
        <td></td>
        <a href='JavaScript:agregarCampo();'> Agregar campo de captura </a>
      </tr>
   </table>

</form>

Ahora, para poder agregar campos de manera dinámica a un formulario deberemos establecer primero un contenedor de los elementos. Para ello usaremos un DIV que definiremos de la siguiente manera:

<div id="contenedorcampos">

</div>

en “contenedorcampos” es donde todos los elementos que vamos a crear irán siendo agrupados. De esa manera podremos controlar siempre la manera en que se visualizarán. Este div debe incrustarse dentro de los tags del formulario quedando el bloque completo de la siguiente manera:

<form id="formdinamico" name="formdinamico" action="prueba.php">

   <table border="0" width="100%">   
      <tr>
        <td></td>
        <a href='JavaScript:agregarCampo();'> Agregar campo de captura </a>
      </tr>
   </table> 

   <div id="contenedorcampos">

   </div>

  </form>

Una vez que tenemos definido el formulario y él vínculo para ir agregando campos vamos a crear un archivo prueba.js donde codificaremos las funciones destinadas al control de los campos.

Lo primero que haremos en prueba.js será definir una variable que almacene el número de controles creados. La definiremos de la siguiente manera:

var campos = 1;

la variable “campos” nos permitirá como mencioné previamente llevar un registro de los controles creados dentro del formulario, además nos servirá para identificar a cada control.

Ahora, vamos a definir la función responsable de la creación de cada control:

function agregarCampo(){
  campos = campos + 1;
  var NvoCampo= document.createElement("div");
  NvoCampo.id= "divcampo_"+(campos);
  NvoCampo.innerHTML= 
     "<table>" +
     "   <tr>" +
     "     <td nowrap='nowrap'>" +
     "        <input type='text' size='50' name='articu_" + campos + 
                   "' id='articu_" + campos + "'>" +
     "     </td>" +
     "     <td nowrap='nowrap'>" +
     "        <a href='JavaScript:quitarCampo(" + campos +");'> Quitar </a>" +
     "     </td>" +
     "   </tr>" +
     "</table>";
   var contenedor= document.getElementById("contenedorcampos");
   contenedor.appendChild(NvoCampo);
}

como puede observarse, la función agregaCampo es responsable de agregar un bloque Html a nuestro contenedor. El nuevo bloque Html contiene los tags necesarios para definir un nuevo control con su propio identificador como puede notarse en la concatenación del nombre de campo y el número de control.

Ahora, ¿qué  sucede si alguno de los campos creados no es necesario?, para ello vamos a definir la siguiente función:

function quitarCampo(iddiv){
  var eliminar = document.getElementById("divcampo_" + iddiv);
  var contenedor= document.getElementById("contenedorcampos");
  contenedor.removeChild(eliminar);
}

esta función será responsable de remover un campo creado de manera dinámica y es incluida dentro de la creación de nuevos campos.

una vez que tenemos todo definido vamos a ejecutar en nuestro navegador la página y veremos lo siguiente:

camposdinamicos Ahora, para probar la funcionalidad de nuestro formulario de campos dinámicos, crearemos el archivo prueba.php y agregaremos lo siguiente:

<?php
  print_r($_REQUEST);
?>

Al ejecutar nuestra página de prueba nos encontraremos una salida conteniendo lo siguiente:

 

Array
(
    [articu_2] => campo1
    [articu_3] => campo2
    [articu_4] => campo3
    [articu_5] => campo4
    [Guardar] => Guardar
    [PHPSESSID] => gr4mmav8kvs2e3kn2782udp494
)

 

El código fuente de este artículo podrán encontrarlo aquí

45 Comments

  1. hola oye disculpa tengo un problema y espero y me puedas ayudar necesito hacer un formulario dinamico como el que creaste pero este a su ves debe de tener otro subformulario, el cual tambien puede ir creciendo como quiera el usuario… no se si me puedas ayudar ya hise la parte del formulario principal pero a la hora de hacer la conexión con el segundo “.js” no la hace y obvio quiero que me regreso todos los datos de los formularios … ojalá y me puedas ayudar de antemano gracias

  2. Buen dia,,probe el codigo pero la salida queda visible para el usuario ??

    123456789 Array ( [articu_2] => campo1 [articu_3] => campo2 [articu_4] => campo3 [articu_5] => campo4 [Guardar] => Guardar [PHPSESSID] => gr4mmav8kvs2e3kn2782udp494 )

    • Si observas en el print que hice del post, los datos que agregamos son enviados, por lo que si agregas un identificador de campo dinámico al nombre de cada input, podrás identificarlos y agregarlos a tu base de datos.

      • Saludos cordiales

        según tu ejemplo y los paso que seguí obtengo identificadores dinámicos, me explico

        si agrego 3 campos tengo nombre_1, nombre_2, nombre_3

        pero cada ves que se ocupe el formulario habrá una cantidad diferente, la consulta en si es ¿El nombre del campo dinamico debe ser para todos nombre o tiene que ir con un valor como lo muestra el ejemplo? y la otra consulta es ¿En el caso que el nombre del campo tenga que ir con un valor numerico como lo inserto en la BD, con un for, un while, o con algún otro anidamiento????

          • Saludos Cordiales

            Mira aun me queda la siguiente duda, logre hacer que almacenara en la BD, pero no de la forma que yo quiero

            tengo el siguiente código, si esta mal favor de indicar el error

            foreach($_POST as $key => $value){
            $sql = (“insert into productos_oc(id_poc, num_oc, item, descrip, cantidad) value (NULL, ‘$orden’, ‘{$value}’, ‘{$value}’, ‘{$value}’)”);
            $inserta = $conexion->prepare($sql);
            $inserta->execute();
            };

            la tabla que tengo es asi

            id_poc, num_oc, item, descrip, cantidad
            1

          • Saludos Cordiales

            Mira aun me queda la siguiente duda, logre hacer que almacenara en la BD, pero no de la forma que yo quiero

            tengo el siguiente código, si esta mal favor de indicar el error

            foreach($_POST as $key => $value){
            $sql = (“insert into productos_oc(id_poc, num_oc, item, descrip, cantidad) value (NULL, ‘$orden’, ‘{$value}’, ‘{$value}’, ‘{$value}’)”);
            $inserta = $conexion->prepare($sql);
            $inserta->execute();
            };

            la tabla que tengo es asi

            id_poc, num_oc, item, descrip, cantidad
            1

          • Saludos Cordiales

            Mira aun me queda la siguiente duda, logre hacer que almacenara en la BD, pero no de la forma que yo quiero

            tengo el siguiente código, si esta mal favor de indicar el error

            foreach($_POST as $key => $value){
            $sql = (“insert into productos_oc(id_poc, num_oc, item, descrip, cantidad) value (NULL, ‘$orden’, ‘{$value}’, ‘{$value}’, ‘{$value}’)”);
            $inserta = $conexion->prepare($sql);
            $inserta->execute();
            };

            la tabla que tengo es asi

            id_poc, num_oc, item, descrip, cantidad
            1

          • Saludos Cordiales

            Mira aun me queda la siguiente duda, logre hacer que almacenara en la BD, pero no de la forma que yo quiero

            tengo el siguiente código, si esta mal favor de indicar el error

            foreach($_POST as $key => $value){
            $sql = (“insert into productos_oc(id_poc, num_oc, item, descrip, cantidad) value (NULL, ‘$orden’, ‘{$value}’, ‘{$value}’, ‘{$value}’)”);
            $inserta = $conexion->prepare($sql);
            $inserta->execute();
            };

            la tabla que tengo es asi

            id_poc, num_oc, item, descrip, cantidad
            1

  3. Disculpe por no terminan lo que quería indicar

    La tabla que tengo es

    id_poc num_oc item descrip cantidad
    1 2424x Telefono 9 botones 5

    Esa es la idea de como se debe almacenar, pero lo que esta haciendo el código es:

    id_poc num_oc item descrip cantidad
    1 2424x Telefono
    2 2424x 9 botones
    3 2424x 5

    Como puedo hacer para que se almacene de la forma correcta????

  4. OK, encontré solución para lo que buscaba

    en ves de usar un foreach agregue dentro del form un contador que lleva la castidad de filas que se agregas dinamicamente, aqui dejo el codigo, ojala les sirva

    $contador = $_POST[“contador”];
    for($i = 1; $i prepare($sql);
    $inserta->execute();

    }

  5. Buen día, antes de nada gracias por el aporte y por los comentarios.

    Quería pedir un poquillo de ayuda.
    El tema es que me gustaría que el formulario llevase un par de campos más a parte de los dinámicos, por ejemplo: nombre, apellido, email.

    ¿Cómo podría hacer esto y recuperar los valores de estos campos y los valores dinámicos?

    Si utilizo este código me trae todas las variables POST pero la variable nombre, apellidos y email me las duplica.

    foreach($_POST as $key => $value){
    echo “$value”.””;
    }

    Esto es lo que trato de hacer, pero me duplica los 3 primeros valores (nombre, apellidos, email)

    echo $_POST[“nombre”].””;
    echo $_POST[“apellidos”].””;
    echo $_POST[“email”].””;

    foreach($_POST as $key => $value){
    echo “$value”.””;
    }

    A ver si me podéis echar una mano. Muchas gracias.

  6. Hola, primero agradecerte el aporte.
    Tengo un problema, y es que estoy usando este ejemplo para añadir dinámicante selects, que toman sus datos desde una bbdd. El problema está en que innerHTML reemplaza por y el select aparece vacío, estoy investgando y por más que miro no hay forma. Me puedes echar una mano? Gracias.

  7. Hola mi consulta es: ¿como se puede almacenar en la BD varios input a la vez?, e investigado pero no encuentro la solución ya que en casi todos los ejemplos es con un solo input
    De antemano muchas graciass.

  8. Gracias por el código es justo lo que necesito, sin embargo aun no puedo hacer para almacenar los datos en una BDD, Podrías poner claramente como se hace?, por favor
    He buscado por Internet y nada.
    Saludos.

    • Almacenar los datos en la base de datos dependerá de la estructura de la tabla o tablas destino. Que te parece si aportas un poco más de información sobre tu problema y en base a ello buscamos la solución. Saludos.

  9. Hola, este script esta muy bueno para un proyecto que voy a comenzar a realizar, sin embargo he estado tratando de modificar el js para que cuando se presione Agregar campo de captura este input quede automaticamente en autofocus, y que al presionar una tecla por ejemplo enter o cualquiera, se agregue otro sin darle click nuevamente al link para agregar este nuevo campo. Sin embargo he estado bloqueado en esas dos funciones extras, podrias ayudarme con eso, gracias brother, muy bueno su tuto.

Deja un comentario