Я хочу автоматически добавлять новые формы в набор форм Django, используя Ajax, так что, когда пользователь нажимает кнопку «добавить», он запускает JavaScript, который добавляет новую форму (которая является частью набора форм) на страницу.
260
Ответы:
Вот как я это делаю, используя jQuery :
Мой шаблон:
В файле JavaScript:
Что оно делает:
cloneMore
принимаетselector
в качестве первого аргумента, аtype
формы - в качестве второго. Чтоselector
нужно сделать, это передать то, что он должен дублировать. В этом случае я передаю егоdiv.table:last
так, что jQuery ищет последнюю таблицу с классомtable
.:last
Часть этого важно , потому чтоselector
также используется для определения того, что новая форма будет вставлена после. Скорее всего, вы захотите это в конце остальных форм.type
Аргумент , так что мы можем обновитьmanagement_form
поле, в частностиTOTAL_FORMS
, а также фактические поля формы. Если у вас есть форма, полная, скажем,Client
моделей, поля управления будут иметь идентификаторыid_clients-TOTAL_FORMS
иid_clients-INITIAL_FORMS
, а поля формы будут в форматеid_clients-N-fieldname
сN
являющийся номером формы, начиная с0
. Таким образом, с помощьюtype
аргументаcloneMore
функция смотрит на то, сколько форм существует в настоящее время, и проходит через каждый ввод и метку внутри новой формы, заменяя все имена / идентификаторы полей чем-то вродеid_clients-(N)-name
toid_clients-(N+1)-name
и так далее. После завершения обновляетTOTAL_FORMS
поле, чтобы отразить новую форму, и добавляет его в конец набора.Эта функция особенно полезна для меня, потому что способ ее настройки позволяет использовать ее в приложении, когда я хочу предоставить больше форм в наборе форм, и не требует наличия скрытой формы «шаблона» для дублирования. пока я передаю его имя набора форм и формат, в котором выложены формы. Надеюсь, поможет.
источник
prefix
члену объекта Formset. Это должно соответствовать значениюtype
аргументаcloneMore
функции.Упрощенная версия ответа Паоло с использованием
empty_form
шаблона.источник
CompetitorFormSet = modelformset_factory(ProjectCompetitor, formset=CompetitorFormSets)
ctx['competitor_form_set'] = CompetitorFormSet(request.POST)
я получаю только одну форму, в чистом методе. не могли бы вы объяснить, как с этим бороться во взглядах?empty_form
), что я ценю.Я разместил фрагмент приложения, над которым работал некоторое время назад. Похож на Paolo, но также позволяет удалять формы.
источник
Предложение Паоло прекрасно работает с одним предупреждением - кнопками браузера назад / вперед.
Динамические элементы, созданные с помощью скрипта Паоло, не будут отображаться, если пользователь вернется в набор форм с помощью кнопки «назад / вперед». Проблема, которая может быть нарушителем соглашения для некоторых.
Пример:
1) Пользователь добавляет две новые формы в форму с помощью кнопки «Добавить»
2) Пользователь заполняет формы и отправляет форму
3) Пользователь нажимает кнопку возврата в браузере
4) Formset теперь приведен к исходной форме, все динамически добавленные формы отсутствуют
Это не является дефектом сценария Паоло вообще; но факт жизни с манипуляциями домом и кешем браузера.
Я полагаю, что можно сохранить значения формы в сеансе и использовать магию ajax, когда набор форм загружается, чтобы снова создать элементы и перезагрузить значения из сеанса; но в зависимости от того, насколько анальным вы хотите быть с одним и тем же пользователем и несколькими экземплярами формы, это может стать очень сложным.
У кого-нибудь есть хорошее предложение для решения этой проблемы?
Спасибо!
источник
Проверьте следующие решения для динамических форм django:
http://code.google.com/p/django-dynamic-formset/
https://github.com/javisantana/django-dinamyc-form/tree/master/frm
Они оба используют jQuery и являются специфичными для django. Первый кажется немного более отлаженным и предлагает загрузку, которая идет с демо, которые превосходны.
источник
Имитация и подражание:
<input>
поля.<input>
изменились поля.Хотя я знаю, что наборы форм используют специальные скрытые
<input>
поля и приблизительно знают, что должен делать скрипт, я не вспоминаю подробности из головы. То, что я описал выше, это то, что я буду делать в вашей ситуации.источник
Для этого есть плагин jquery , я использовал его с inline_form, установленным в Django 1.3, и он отлично работает, включая предварительное заполнение, добавление, удаление форм на стороне клиента и множественные наборы inline_formsets.
источник
Одним из вариантов было бы создать formset с каждой возможной формы, но сначала установить Ненужные формы для спрятался - то есть
display: none;
. Когда необходимо отобразить форму, установите для ее отображения css значениеblock
или другое подходящее.Не зная более подробной информации о том, что делает ваш «Аякс», сложно дать более подробный ответ.
источник
Еще одна версия cloneMore, которая позволяет проводить выборочную очистку полей. Используйте его, когда вам нужно предотвратить стирание нескольких полей.
источник
Есть небольшая проблема с функцией cloneMore. Так как он также очищает значение автоматически сгенерированных скрытых полей django, он заставляет django жаловаться, если вы пытаетесь сохранить набор форм с более чем одной пустой формой.
Вот исправление:
источник
Я думаю, что это гораздо лучшее решение.
Как бы вы создали динамический набор форм в Django?
Делает ли что-то клон?
источник
Для программистов, которые ищут ресурсы, чтобы немного лучше понять вышеприведенные решения:
Django Dynamic Formsets
После прочтения вышеупомянутой ссылки, документация Django и предыдущие решения должны иметь намного больше смысла.
Документация Django Formset
В качестве краткого изложения того, что меня смутило: Форма управления содержит обзор форм внутри. Вы должны сохранять эту информацию точной, чтобы Django знал о формах, которые вы добавляете. (Сообщество, пожалуйста, дайте мне предложения, если некоторые из моих формулировок здесь не так. Я новичок в Django.)
источник
@Paolo Bergantino
клонировать все прикрепленные обработчики просто изменить строку
для
чтобы предотвратить эту проблему.
источник
Да, я бы также рекомендовал просто выводить их в html, если у вас есть конечное количество записей. (Если вы этого не сделаете, вам придется использовать другой метод).
Вы можете скрыть их так:
Тогда JS действительно прост:
источник
Поскольку все ответы выше используют jQuery и делают некоторые вещи немного сложнее, я написал следующий скрипт:
Сначала вы должны установить для auto_id значение false и отключить дублирование идентификатора и имени. Поскольку входные имена должны быть уникальными в их форме, вся идентификация выполняется с ними, а не с идентификаторами. Вы также должны заменить
form
,type
и контейнер из formset. (В приведенном выше примереchoices
)источник