Ich möchte mit Ajax automatisch neue Formulare zu einem Django-Formularsatz hinzufügen. Wenn der Benutzer auf die Schaltfläche "Hinzufügen" klickt, wird JavaScript ausgeführt, das der Seite ein neues Formular (das Teil des Formularsatzes ist) hinzufügt.
260
Antworten:
So mache ich es mit jQuery :
Meine Vorlage:
In einer Javascript-Datei:
Was es macht:
cloneMore
akzeptiertselector
als erstes Argument und dastype
von formset als zweites. Was dasselector
tun sollte, ist es zu übergeben, was es duplizieren sollte. In diesem Fall übergebe ich esdiv.table:last
so, dass jQuery nach der letzten Tabelle mit einer Klasse von suchttable
. Der:last
Teil davon ist wichtig, da derselector
auch verwendet wird, um zu bestimmen, wonach das neue Formular eingefügt wird. Höchstwahrscheinlich möchten Sie es am Ende der restlichen Formulare. Dastype
Argument ist, dass wir insbesondere dasmanagement_form
FeldTOTAL_FORMS
sowie die tatsächlichen Formularfelder aktualisieren können . Wenn Sie ein Formularset mit beispielsweiseClient
Modellen haben, haben die Verwaltungsfelder IDs vonid_clients-TOTAL_FORMS
undid_clients-INITIAL_FORMS
, während die Formularfelder das Formatid_clients-N-fieldname
with habenN
ist die Formularnummer, beginnend mit0
. Mit demtype
Argument prüft diecloneMore
Funktion also, wie viele Formulare derzeit vorhanden sind, und durchläuft jede Eingabe und Beschriftung im neuen Formular, wobei alle Feldnamen / IDs von so etwas wieid_clients-(N)-name
bisid_clients-(N+1)-name
usw. ersetzt werden. Nachdem es fertig ist, aktualisiert es dasTOTAL_FORMS
Feld, um das neue Formular wiederzugeben, und fügt es am Ende des Satzes hinzu.Diese Funktion ist für mich besonders hilfreich, da ich sie aufgrund ihrer Einrichtung in der gesamten App verwenden kann, wenn ich mehr Formulare in einem Formularsatz bereitstellen möchte, und kein verstecktes "Vorlagen" -Formular zum Duplizieren erforderlich bin Solange ich es übergebe, den Namen des Formularsatzes und das Format, in dem die Formulare angeordnet sind. Ich hoffe es hilft.
quelle
prefix
Mitglied des Formset-Objekts einen Wert zuweisen müssen. Dies sollte der gleiche Wert sein wie dastype
Argument für diecloneMore
Funktion.Vereinfachte Version von Paolos Antwort
empty_form
als Vorlage.quelle
CompetitorFormSet = modelformset_factory(ProjectCompetitor, formset=CompetitorFormSets)
ctx['competitor_form_set'] = CompetitorFormSet(request.POST)
bekomme ich nur ein Formular, in sauberer Methode. Können Sie bitte erklären, wie Sie in Ansichten damit umgehen sollen?empty_form
) hervorragend , was ich sehr schätze.Ich habe einen Ausschnitt aus einer App gepostet, an der ich vor einiger Zeit gearbeitet habe. Ähnlich wie bei Paolo, ermöglicht aber auch das Löschen von Formularen.
quelle
Paolos Vorschlag funktioniert wunderbar mit einer Einschränkung - den Zurück / Vorwärts-Schaltflächen des Browsers.
Die mit Paolos Skript erstellten dynamischen Elemente werden nicht gerendert, wenn der Benutzer über die Schaltfläche Zurück / Vorwärts zum Formularsatz zurückkehrt. Ein Problem, das für manche ein Deal Breaker sein kann.
Beispiel:
1) Der Benutzer fügt dem Formularsatz über die Schaltfläche "Mehr hinzufügen" zwei neue Formulare hinzu
2) Der Benutzer füllt die Formulare aus und sendet das Formularset
3) Der Benutzer klickt im Browser auf die Schaltfläche "Zurück"
4) Formset wird jetzt auf das ursprüngliche Formular reduziert, alle dynamisch hinzugefügten Formulare sind nicht vorhanden
Dies ist überhaupt kein Fehler in Paolos Skript; aber eine Tatsache des Lebens mit Dom-Manipulation und Browser-Cache.
Ich nehme an, man könnte die Werte des Formulars in der Sitzung speichern und etwas Ajax-Magie haben, wenn das Formularset geladen wird, um die Elemente erneut zu erstellen und die Werte aus der Sitzung neu zu laden. Aber je nachdem, wie anal Sie über denselben Benutzer und mehrere Instanzen des Formulars sein möchten, kann dies sehr kompliziert werden.
Hat jemand einen guten Vorschlag, um damit umzugehen?
Vielen Dank!
quelle
Schauen Sie sich die folgenden Lösungen für dynamische Django-Formen an:
http://code.google.com/p/django-dynamic-formset/
https://github.com/javisantana/django-dinamyc-form/tree/master/frm
Beide verwenden jQuery und sind Django-spezifisch. Der erste scheint etwas ausgefeilter zu sein und bietet einen Download mit Demos, die ausgezeichnet sind.
quelle
Simulieren und imitieren:
<input>
Felder.<input>
Felder geändert haben.Obwohl ich weiß, dass Formsets spezielle versteckte
<input>
Felder verwenden und ungefähr wissen, was das Skript tun muss, erinnere ich mich nicht an die Details auf der Oberseite meines Kopfes. Was ich oben beschrieben habe, würde ich in Ihrer Situation tun.quelle
Hierfür gibt es ein jquery-Plugin . Ich habe es mit inline_form in Django 1.3 verwendet und es funktioniert einwandfrei, einschließlich Vorbelegung, Hinzufügen, Entfernen von clientseitigen Formularen und mehreren inline_formsets.
quelle
Eine Möglichkeit wäre, mit jedem möglichen Formular ein Formularset zu erstellen, die nicht erforderlichen Formulare jedoch zunächst auf ausgeblendet zu setzen
display: none;
. Wenn ein Formular angezeigt werden muss, setzen Sie die CSS-Anzeige aufblock
oder was auch immer angemessen ist.Ohne mehr Details darüber zu wissen, was Ihr "Ajax" tut, ist es schwierig, eine detailliertere Antwort zu geben.
quelle
Eine weitere cloneMore-Version, die die selektive Bereinigung von Feldern ermöglicht. Verwenden Sie diese Option, wenn Sie verhindern möchten, dass mehrere Felder gelöscht werden.
quelle
Es gibt ein kleines Problem mit der Funktion cloneMore. Da auch der Wert der automatisch von Django generierten ausgeblendeten Felder bereinigt wird, beschwert sich Django, wenn Sie versuchen, ein Formularset mit mehr als einem leeren Formular zu speichern.
Hier ist ein Fix:
quelle
Ich denke, das ist eine viel bessere Lösung.
Wie würden Sie ein dynamisches Formset in Django erstellen?
Klonen Dinge nicht:
quelle
Für die Programmierer da draußen, die nach Ressourcen suchen, um die oben genannten Lösungen ein wenig besser zu verstehen:
Django Dynamic Formsets
Nach dem Lesen des obigen Links sollten die Django-Dokumentation und frühere Lösungen viel sinnvoller sein.
Django Formset-Dokumentation
Als kurze Zusammenfassung dessen, was mich verwirrt hat: Das Verwaltungsformular enthält eine Übersicht über die darin enthaltenen Formulare. Sie müssen diese Informationen korrekt halten, damit Django die von Ihnen hinzugefügten Formulare kennt. (Community, bitte gib mir Vorschläge, wenn ein Teil meiner Formulierung hier nicht stimmt. Ich bin neu in Django.)
quelle
@Paolo Bergantino
Um alle angehängten Handler zu klonen, ändern Sie einfach die Zeile
zum
um dieses Problem zu verhindern .
quelle
Ja, ich würde auch empfehlen, sie nur im HTML-Code zu rendern, wenn Sie eine begrenzte Anzahl von Einträgen haben. (Wenn Sie dies nicht tun, müssen Sie eine andere Methode verwenden).
Sie können sie folgendermaßen verstecken:
Dann ist das js ganz einfach:
quelle
Da alle obigen Antworten jQuery verwenden und einige Dinge etwas komplexer machen, habe ich folgendes Skript geschrieben:
Zuerst sollten Sie auto_id auf false setzen und so die Duplizierung von ID und Name deaktivieren. Da die Eingabenamen in ihrer Form eindeutig sein müssen, erfolgt die gesamte Identifizierung mit ihnen und nicht mit IDs. Sie müssen auch die ersetzen
form
,type
und der Behälter der formset. (Im obigen Beispielchoices
)quelle