Así es como lo hago, usando jQuery :
Mi plantilla:
<h3>My Services</h3>
{{ serviceFormset.management_form }}
{% for form in serviceFormset.forms %}
<div class='table'>
<table class='no_error'>
{{ form.as_table }}
</table>
</div>
{% endfor %}
<input type="button" value="Add More" id="add_more">
<script>
$('#add_more').click(function() {
cloneMore('div.table:last', 'service');
});
</script>
En un archivo javascript:
function cloneMore(selector, type) {
var newElement = $(selector).clone(true);
var total = $('#id_' + type + '-TOTAL_FORMS').val();
newElement.find(':input').each(function() {
var name = $(this).attr('name').replace('-' + (total-1) + '-','-' + total + '-');
var id = 'id_' + name;
$(this).attr({'name': name, 'id': id}).val('').removeAttr('checked');
});
newElement.find('label').each(function() {
var newFor = $(this).attr('for').replace('-' + (total-1) + '-','-' + total + '-');
$(this).attr('for', newFor);
});
total++;
$('#id_' + type + '-TOTAL_FORMS').val(total);
$(selector).after(newElement);
}
Que hace:
cloneMore
acepta selector
como primer argumento, y type
of formset como el segundo. Lo que selector
debería hacer es pasarle lo que debería duplicar. En este caso, lo paso div.table:last
para que jQuery busque la última tabla con una clase de table
. La :last
parte de esto es importante porque selector
también se usa para determinar después de qué se insertará el nuevo formulario. Es más que probable que lo desee al final del resto de los formularios. El type
argumento es para que podamos actualizar el management_form
campo, en particular TOTAL_FORMS
, así como los campos de formulario reales. Si tiene un conjunto de formularios lleno de, por ejemplo, Client
modelos, los campos de administración tendrán ID id_clients-TOTAL_FORMS
y id_clients-INITIAL_FORMS
, mientras que los campos de formulario estarán en un formato de id_clients-N-fieldname
conN
siendo el número de formulario, comenzando con 0
. Así, con el type
argumento de las cloneMore
miradas de la función de cuántas formas hay actualmente, y pasa a través de cada entrada y etiqueta dentro de la nueva forma de la sustitución de todos los nombres de campo / nº ID de algo así como id_clients-(N)-name
que id_clients-(N+1)-name
y así sucesivamente. Una vez finalizado, actualiza el TOTAL_FORMS
campo para reflejar el nuevo formulario y lo agrega al final del conjunto.
Esta función es particularmente útil para mí porque la forma en que está configurada me permite usarla en toda la aplicación cuando quiero proporcionar más formularios en un conjunto de formularios, y no hace que necesite tener un formulario oculto de "plantilla" para duplicar siempre que lo pase, el nombre del formulario y el formato en que se presentan los formularios. Espero eso ayude.