Chcę automatycznie dodawać nowe formularze do zestawu formularzy Django za pomocą Ajax, aby gdy użytkownik kliknie przycisk „dodaj”, uruchomi JavaScript, który dodaje nowy formularz (który jest częścią zestawu formularzy) do strony.
260
Odpowiedzi:
Tak to robię za pomocą jQuery :
Mój szablon:
W pliku javascript:
Co to robi:
cloneMore
przyjmujeselector
jako pierwszy argument, atype
formset jako drugi. To, coselector
należy zrobić, to przekazać to, co powinno się powielić. W tym przypadku przekazuję godiv.table:last
, aby jQuery szukał ostatniej tabeli z klasątable
. Ta:last
część jest ważna, ponieważselector
służy również do określenia, po czym zostanie wstawiony nowy formularz. Bardziej niż prawdopodobne, że będziesz tego chciał na końcu pozostałych formularzy.type
Argument jest tak, że możemy zaktualizowaćmanagement_form
pole, zwłaszczaTOTAL_FORMS
, jak również rzeczywistych pól formularza. Jeśli masz zestaw formularzy pełen, powiedzmy,Client
modeli, pola zarządzania będą miały identyfikatoryid_clients-TOTAL_FORMS
iid_clients-INITIAL_FORMS
, podczas gdy pola formularza będą miały formatid_clients-N-fieldname
zN
będący numerem formularza, zaczynając od0
. Więc ztype
argumentucloneMore
wygląd funkcyjne, jak wiele form Obecnie są i przechodzi przez każdego wejścia i etykiety wewnątrz nowej formie zastępujący wszystkie nazwy pól / numery z czegoś podobnegoid_clients-(N)-name
doid_clients-(N+1)-name
i tak dalej. Po zakończeniu aktualizujeTOTAL_FORMS
pole, aby odzwierciedlić nowy formularz i dodaje go na końcu zestawu.Ta funkcja jest dla mnie szczególnie pomocna, ponieważ sposób jej konfiguracji pozwala mi korzystać z niej w całej aplikacji, gdy chcę udostępnić więcej formularzy w zestawie formularzy, i nie wymaga posiadania ukrytego formularza „szablonu” do kopiowania tak długo, jak go przekażę, nazwa zestawu formularzy i format, w jakim formularze są ułożone. Mam nadzieję, że to pomoże.
źródło
prefix
elementu obiektu Formset. Powinna mieć tę samą wartość cotype
argumentcloneMore
funkcji.Uproszczona wersja odpowiedzi Paolo wykorzystująca
empty_form
jako szablon.źródło
CompetitorFormSet = modelformset_factory(ProjectCompetitor, formset=CompetitorFormSets)
ctx['competitor_form_set'] = CompetitorFormSet(request.POST)
i otrzymuję tylko jeden formularz, w czystej metodzie. czy możesz wyjaśnić, jak sobie z tym poradzić w widokach?empty_form
), co doceniam.Mam napisali fragment z aplikacji pracowałem na jakiś czas temu. Podobne do Paolo, ale umożliwia również usuwanie formularzy.
źródło
Sugestia Paolo działa pięknie z jednym zastrzeżeniem - przyciskami Wstecz / Dalej przeglądarki.
Elementy dynamiczne utworzone za pomocą skryptu Paolo nie będą renderowane, jeśli użytkownik powróci do zestawu formularzy za pomocą przycisku Wstecz / Dalej. Problem, który może w niektórych przypadkach stanowić przeszkodę.
Przykład:
1) Użytkownik dodaje dwa nowe formularze do zestawu formularzy za pomocą przycisku „dodaj więcej”
2) Użytkownik wypełnia formularze i przesyła zestaw formularzy
3) Użytkownik klika przycisk Wstecz w przeglądarce
4) Zestaw formularzy został teraz zredukowany do pierwotnego formularza, nie ma tam wszystkich dynamicznie dodanych formularzy
Nie jest to wcale wada skryptu Paolo; ale faktem jest manipulacja domem i pamięć podręczna przeglądarki.
Przypuszczam, że można zapisać wartości formularza w sesji i mieć trochę magii ajax, gdy zestaw formularzy ładuje się, aby ponownie utworzyć elementy i ponownie załadować wartości z sesji; ale w zależności od tego, jak analny chcesz być na temat tego samego użytkownika i wielu wystąpień formularza, może to być bardzo skomplikowane.
Czy ktoś ma dobrą sugestię, jak sobie z tym poradzić?
Dzięki!
źródło
Sprawdź następujące rozwiązania dla dynamicznych formularzy django:
http://code.google.com/p/django-dynamic-formset/
https://github.com/javisantana/django-dinamyc-form/tree/master/frm
Oba korzystają z jQuery i są specyficzne dla django. Pierwszy wydaje się nieco bardziej dopracowany i oferuje pobieranie, które zawiera w / dema, które są doskonałe.
źródło
Symuluj i naśladuj:
<input>
pola.<input>
zmiany w polach.Chociaż wiem, że zestawy formularzy używają specjalnych ukrytych
<input>
pól i wiem mniej więcej, co skrypt musi zrobić, nie pamiętam szczegółów z góry głowy. Powyżej opisałem, co zrobiłbym w twojej sytuacji.źródło
Jest do tego wtyczka jquery , użyłem jej z zestawem inline_form w Django 1.3 i działa idealnie, w tym prepopulation, dodawanie, usuwanie i wiele formularzy po stronie klienta.
źródło
Jedną z opcji byłoby utworzenie zestawu formularzy z każdą możliwą formą, ale początkowo ustaw niepotrzebne formularze na ukryte - tj
display: none;
. Gdy konieczne jest wyświetlenie formularza, ustaw jego wyświetlanie css nablock
lub cokolwiek jest odpowiednie.Nie znając więcej szczegółów na temat tego, co robi Twój „Ajax”, trudno jest podać bardziej szczegółową odpowiedź.
źródło
Kolejna wersja cloneMore, która pozwala na selektywną dezynfekcję pól. Użyj go, gdy chcesz zapobiec skasowaniu kilku pól.
źródło
Istnieje niewielki problem z funkcją cloneMore. Ponieważ usuwa również wartość ukrytych pól automatycznie generowanych przez django, powoduje, że django narzeka, jeśli spróbujesz zapisać zestaw formularzy z więcej niż jednym pustym formularzem.
Oto poprawka:
źródło
Myślę, że to znacznie lepsze rozwiązanie.
Jak stworzyłbyś dynamiczny zestaw formularzy w Django?
Czy klonowanie rzeczy nie:
źródło
Aby koderzy szukający zasobów mogli lepiej zrozumieć powyższe rozwiązania:
Dynamiczne zestawy formularzy Django
Po przeczytaniu powyższego linku dokumentacja Django i poprzednie rozwiązania powinny mieć o wiele większy sens.
Dokumentacja zestawu Django
Jako krótkie podsumowanie tego, co mnie pomyliło: Formularz zarządzania zawiera przegląd formularzy w nim zawartych. Musisz zachować dokładność tych informacji, aby Django wiedział o dodawanych formularzach. (Społeczność, proszę o sugestie, jeśli niektóre z moich sformułowań są tutaj. Jestem nowy w Django.)
źródło
@Paolo Bergantino
aby sklonować wszystkie dołączone programy obsługi, wystarczy zmodyfikować linię
dla
aby zapobiec temu problemowi.
źródło
Tak, polecam również renderowanie ich w pliku HTML, jeśli masz skończoną liczbę wpisów. (Jeśli nie, będziesz musiał użyć innej metody).
Możesz je ukryć w następujący sposób:
Zatem js jest naprawdę prosty:
źródło
Ponieważ wszystkie powyższe odpowiedzi używają jQuery i sprawiają, że niektóre rzeczy są nieco skomplikowane, napisałem następujący skrypt:
Najpierw powinieneś ustawić auto_id na false, a zatem wyłączyć powielanie identyfikatora i nazwy. Ponieważ nazwy wejściowe muszą być tam unikalne, cała identyfikacja odbywa się za ich pomocą, a nie za pomocą identyfikatorów. Trzeba też wymienić
form
,type
a pojemnik z formset. (W powyższym przykładziechoices
)źródło