Formularios HTML con campos dinámicos en JavaScript

Hoy me he tropezado con una necesidad en un formulario y es que el número de campos tenía que ser dinámico y no predefinido, para que no sea el ejemplo con el que he tenido que lidiar y sea algo más entretenido vamos a pensar en un formulario en el que introduzcamos las canciones de un CD de música, no sabemos como se llama el CD y lo mejor, no sabemos cuantas canciones tiene.

Así que vamos a hacer un formulario que pida el nombre del CD, el autor y todas las canciones junto con la duración de cada una.

Para que quede mono el formulario podemos ir a lo fácil y usar bootstrap, para definir los cuadros podemos ir a shoelace.io que es una web que nos ayudará a crear los cuadros de una forma muy fácil y visual, en mi caso:

shoelace

El código que nos ha generado es el siguiente:

<div class="container">
    <div class="row">
        <div class="col-md-offset-1 col-md-4"></div>
        <div class="col-md-4"></div>
    </div>
    <div class="row">
        <div class="col-md-offset-1 col-md-6"></div>
        <div class="col-md-2"></div>
    </div>
    <div class="row">
        <div class="col-md-offset-1 col-md-6"></div>
        <div class="col-md-2"></div>
    </div>
</div>

Obviamente para estas cajas no es necesario usar ninguna aplicación externa, pero que sepáis que existe, a mi me ha venido muy bien.

En cuanto tenemos esto procedemos a meter nuestro formulario ahí dentro.

<div class="container">
    <h3>Formulario de canciones de CD</h3>
    <form action="relleno_de_cds.php" id="formulario" method="post">
    <div class="row">
        <div class="col-md-offset-1 col-md-4"><label>Nombre CD</label></div>
        <div class="col-md-4"><input class="form-control" name="nombre_cd" type="text"/></div>
    </div>
    <div class="row">
        <div class="col-md-offset-1 col-md-6"><label>T&iacute;tulo canci&oacute;n</label></div>
        <div class="col-md-2"><label>Duraci&oacute;n</label></div>
        <div class="col-md-1"><input type="button" class="btn btn-success" id="add_cancion()" onClick="addCancion()" value="+" /></div>
    </div>
    <!-- El id="canciones" indica que la función de JavaScript dejará aquí el resultado -->
    <div class="row" id="canciones">
    </div>
    </form>
</div>

Como primer paso hemos rellenado la plantilla que nos ha generado la aplicación de antes para usar los campos para distribuir el formulario, sólo hemos añadido un pequeño detalle, y es ese botón «+» que han en la segunda caja y que solo ocupa una columna. La distribución de las columnas es la de bootstrap.

Por supuesto en la cabecera hemos metido el css indicado

<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

Y en cuanto al javascript utilizado la función addCancion() que lo que hace es añadir al div canciones, el último y que aparece vacío en el HTML de arriba dos cajas más con los inputs del formulario.

Por supuesto, cada vez que se le da al «+» verde se crea una nueva fila

<script>
a = 0;
function addCancion(){
        a++;

        var div = document.createElement('div');
        div.setAttribute('class', 'form-inline');
            div.innerHTML = '<div style="clear:both" class="cancion_'+a+' col-md-offset-1 col-md-6"><input class="form-control" name="cancion_'+a+'" type="text"/></div><div class="cancion_'+a+' col-md-2""><input class="form-control" name="duracion_'+a+'" type="text"/></div>';
            document.getElementById('canciones').appendChild(div);document.getElementById('canciones').appendChild(div);
}
</script>

El formulario en un navegador al final queda como la imagen que os pongo a continuación:

formulairo_cd

El código completo, todo juntito, es el siguiente:

<!DOCTYPE html>
<html>
<head>

<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">


<script>
a = 0;
function addCancion(){
        a++;

        var div = document.createElement('div');
        div.setAttribute('class', 'form-inline');
            div.innerHTML = '<div style="clear:both" class="cancion_'+a+' col-md-offset-1 col-md-6"><input class="form-control" name="cancion_'+a+'" type="text"/></div><div class="cancion_'+a+' col-md-2""><input class="form-control" name="duracion_'+a+'" type="text"/></div>';
            document.getElementById('canciones').appendChild(div);document.getElementById('canciones').appendChild(div);
}
</script>


</head>

<body>
<div class="container">
    <h3>Formulario de canciones de CD</h3>
    <form action="formulario2.html" id="formulario" method="get">
    <div class="row">
        <div class="col-md-offset-1 col-md-4"><label>Nombre CD</label></div>
        <div class="col-md-4"><input class="form-control" name="nombre_cd" type="text"/></div>
    </div>
    <div class="row">
        <div class="col-md-offset-1 col-md-6"><label>T&iacute;tulo canci&oacute;n</label></div>
        <div class="col-md-2"><label>Duraci&oacute;n</label></div>
        <div class="col-md-1"><input type="button" class="btn btn-success" id="add_cancion()" onClick="addCancion()" value="+" /></div>
    </div>
    <!-- El id="canciones" indica que la función de JavaScript dejará aquí el resultado -->
    <div class="row" id="canciones">
    </div>
    </form>
</div>

</body>
</html>