Voici comment je le fais, en utilisant jQuery :
Mon modèle:
<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>
Dans un fichier 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);
}
Ce qu'il fait:
cloneMore
accepte selector
comme premier argument, et type
de formset comme 2e argument . Ce qu'il selector
faut faire, c'est lui transmettre ce qu'il doit reproduire. Dans ce cas, je le passe div.table:last
pour que jQuery recherche la dernière table avec une classe de table
. La :last
partie est importante car le selector
est également utilisé pour déterminer ce que le nouveau formulaire sera inséré après. Il est plus que probable que vous le souhaiteriez à la fin du reste des formulaires. L' type
argument est que nous pouvons mettre à jour le management_form
champ, notamment TOTAL_FORMS
, ainsi que les champs de formulaire réels. Si vous avez un jeu de formulaires rempli, par exemple, de Client
modèles, les champs de gestion auront des ID de id_clients-TOTAL_FORMS
et id_clients-INITIAL_FORMS
, tandis que les champs de formulaire seront au format id_clients-N-fieldname
avecN
étant le numéro de formulaire, en commençant par 0
. Donc , avec l' type
argument de la cloneMore
fonction ressemble à combien de formes Actuellement , il n'y, et passe par chaque entrée et étiquette à l' intérieur du nouveau formulaire remplaçant tous les noms / ids de quelque chose comme champ id_clients-(N)-name
à id_clients-(N+1)-name
et ainsi de suite. Une fois terminé, il met à jour le TOTAL_FORMS
champ pour refléter le nouveau formulaire et l'ajoute à la fin de l'ensemble.
Cette fonction est particulièrement utile pour moi car la façon dont elle est configurée me permet de l'utiliser dans toute l'application lorsque je veux fournir plus de formulaires dans un jeu de formulaires, et ne me fait pas avoir besoin d'un formulaire "modèle" caché pour dupliquer tant que je lui transmets le nom du jeu de formulaires et le format dans lequel les formulaires sont disposés. J'espère que ça aide.