Saya ingin secara otomatis menambahkan formulir baru ke Django formset menggunakan Ajax, sehingga ketika pengguna mengklik tombol "add" itu menjalankan JavaScript yang menambahkan formulir baru (yang merupakan bagian dari formset) ke halaman.
260
Jawaban:
Ini adalah bagaimana saya melakukannya, menggunakan jQuery :
Templat saya:
Dalam file javascript:
Apa fungsinya:
cloneMore
menerimaselector
sebagai argumen pertama, dantype
formset sebagai argumen ke-2. Apa yangselector
harus dilakukan adalah menyampaikannya apa yang harus digandakan. Dalam hal ini, saya meneruskannyadiv.table:last
sehingga jQuery mencari tabel terakhir dengan kelastable
. Bagian:last
itu penting karenaselector
juga digunakan untuk menentukan apa bentuk baru yang akan dimasukkan setelah. Kemungkinan besar Anda menginginkannya di akhir formulir lainnya. Thetype
argumen adalah agar kita dapat memperbaruimanagement_form
lapangan, terutamaTOTAL_FORMS
, serta kolom formulir yang sebenarnya. Jika Anda memiliki formset penuh dengan, misalnya,Client
model, bidang manajemen akan memiliki IDid_clients-TOTAL_FORMS
danid_clients-INITIAL_FORMS
, sedangkan bidang formulir akan dalam formatid_clients-N-fieldname
denganN
menjadi nomor formulir, dimulai dengan0
. Jadi dengantype
argumencloneMore
fungsi melihat berapa banyak bentuk yang ada saat ini, dan melewati setiap input dan label di dalam formulir baru menggantikan semua nama bidang / id dari sesuatu sepertiid_clients-(N)-name
keid_clients-(N+1)-name
dan seterusnya. Setelah selesai, itu memperbaruiTOTAL_FORMS
bidang untuk mencerminkan formulir baru dan menambahkannya ke akhir set.Fungsi ini sangat membantu saya karena cara pengaturannya memungkinkan saya untuk menggunakannya di seluruh aplikasi ketika saya ingin memberikan lebih banyak formulir dalam sebuah formset, dan tidak membuat saya perlu memiliki formulir "templat" tersembunyi untuk menduplikasi selama saya berikan nama format dan format di mana formulir diletakkan. Semoga ini bisa membantu.
sumber
prefix
anggota Objek Formset. Nilai ini harus sama dengantype
argumen untukcloneMore
fungsi.Versi sederhana dari jawaban Paolo menggunakan
empty_form
sebagai templat.sumber
CompetitorFormSet = modelformset_factory(ProjectCompetitor, formset=CompetitorFormSets)
ctx['competitor_form_set'] = CompetitorFormSet(request.POST)
i Hanya mendapatkan satu formulir, di dalam metode bersih. dapatkah Anda menjelaskan bagaimana menangani ini dalam pandangan?empty_form
), yang saya hargai.Saya telah memposting cuplikan dari aplikasi yang saya kerjakan beberapa waktu lalu. Mirip dengan Paolo, tetapi juga memungkinkan Anda menghapus formulir.
sumber
Saran Paolo bekerja dengan indah dengan satu peringatan - tombol kembali / maju browser.
Elemen dinamis yang dibuat dengan skrip Paolo tidak akan diberikan jika pengguna kembali ke formset menggunakan tombol kembali / maju. Masalah yang mungkin menjadi pemecah kesepakatan bagi sebagian orang.
Contoh:
1) Pengguna menambahkan dua formulir baru ke formset menggunakan tombol "tambah lagi"
2) Pengguna mengisi formulir dan mengirimkan formset
3) Pengguna mengklik tombol kembali di browser
4) Formset sekarang dikurangi menjadi bentuk asli, semua bentuk yang ditambahkan secara dinamis tidak ada
Ini sama sekali bukan cacat pada naskah Paolo; tetapi fakta kehidupan dengan manipulasi dom dan cache browser.
Saya kira orang bisa menyimpan nilai-nilai formulir di sesi dan memiliki beberapa ajax magic ketika formset memuat untuk membuat elemen lagi dan memuat ulang nilai-nilai dari sesi; tetapi tergantung pada seberapa anal Anda ingin tentang pengguna yang sama dan beberapa contoh formulir ini mungkin menjadi sangat rumit.
Adakah yang punya saran bagus untuk menangani ini?
Terima kasih!
sumber
Lihat solusi berikut untuk formulir Django dinamis:
http://code.google.com/p/django-dynamic-formset/
https://github.com/javisantana/django-dinamyc-form/tree/master/frm
Keduanya menggunakan jQuery dan khusus Django. Yang pertama tampaknya sedikit lebih halus dan menawarkan unduhan yang disertai dengan demo yang luar biasa.
sumber
Simulasikan dan tiru:
<input>
bidang.<input>
ladang berubah.Meskipun saya tahu format menggunakan
<input>
bidang tersembunyi khusus dan tahu kira-kira apa yang harus dilakukan skrip, saya tidak mengingat detail dari atas kepala saya. Apa yang saya jelaskan di atas adalah apa yang akan saya lakukan dalam situasi Anda.sumber
Ada plugin jquery untuk ini , saya menggunakannya dengan set inline_form di Django 1.3, dan berfungsi dengan baik, termasuk prepopulasi, penambahan sisi klien, penghapusan, dan beberapa inline_formsets.
sumber
Salah satu opsi adalah membuat formset dengan setiap form yang mungkin, tetapi pada awalnya mengatur form yang tidak diminta menjadi tersembunyi - yaitu
display: none;
,. Bila perlu untuk menampilkan formulir, atur tampilan css keblock
atau apa pun yang sesuai.Tanpa tahu lebih detail tentang apa yang "Ajax" Anda lakukan, sulit untuk memberikan respons yang lebih detail.
sumber
Versi cloneMore lainnya, yang memungkinkan sanitasi bidang selektif. Gunakan saat Anda perlu mencegah beberapa bidang terhapus.
sumber
Ada masalah kecil dengan fungsi cloneMore. Karena itu juga membersihkan nilai dari bidang tersembunyi yang dihasilkan secara otomatis Django, hal itu menyebabkan Django mengeluh jika Anda mencoba menyimpan suatu formset dengan lebih dari satu formulir kosong.
Ini adalah perbaikan:
sumber
Saya pikir ini adalah solusi yang jauh lebih baik.
Bagaimana Anda membuat format dinamis di Django?
Apakah hal-hal yang dikloning tidak:
sumber
Untuk coders di luar sana yang mencari sumber daya untuk memahami solusi di atas sedikit lebih baik:
Django Dynamic Formsets
Setelah membaca tautan di atas, dokumentasi Django dan solusi sebelumnya seharusnya lebih masuk akal.
Dokumentasi Django Formset
Sebagai ringkasan singkat tentang apa yang membuat saya bingung: Formulir Manajemen berisi tinjauan umum tentang formulir-formulir di dalamnya. Anda harus menjaga agar informasi itu akurat agar Django mengetahui formulir yang Anda tambahkan. (Komunitas, tolong beri saya saran jika beberapa kata-kata saya tidak ada di sini. Saya baru mengenal Django.)
sumber
@ Paolo Bergantino
untuk mengkloning semua handler yang terpasang, cukup modifikasi jalurnya
untuk
untuk mencegah masalah ini.
sumber
Ya, saya juga merekomendasikan untuk menyerahkannya di html jika Anda memiliki jumlah entri yang terbatas. (Jika tidak, Anda harus menggunakan metode lain).
Anda dapat menyembunyikannya seperti ini:
Maka js sangat sederhana:
sumber
Karena semua jawaban di atas menggunakan jQuery dan membuat beberapa hal agak rumit saya menulis skrip berikut:
Pertama, Anda harus mengatur auto_id ke false sehingga menonaktifkan duplikasi id dan nama. Karena nama input harus unik dalam bentuk di sana, semua identifikasi dilakukan dengan mereka dan bukan dengan id. Anda juga harus mengganti
form
,type
dan wadah formset. (Dalam contoh di ataschoices
)sumber