Добавьте динамическую форму в набор форм Django, используя JavaScript правильно

Как добавить динамическую форму в набор форм Django в шаблонах, не раздражая копии вывода шаблона HTML?

У меня есть набор форм с неизвестным количеством форм результатов, и мне нужно добавить несколько форм непосредственно в шаблон, нажав на кнопку.

1 ответ

Решение

Этот ответ основан на посте Ника Лэнга, но мы собираемся упростить этот способ, и нам больше не нужно копировать / вставлять всю форму HTML.

У нас есть встроенный набор форм, который создается в таком виде:

items_formset = inlineformset_factory(Parent, Item, form=ItemForm, extra=1)
item_forms = items_formset()  

Далее нам нужно создать шаблон для формы outset, мы можем сделать это с помощью empty_form свойство экземпляра formset, которое генерирует шаблон формы html, где каждый номер "id" формы заменяется на __prefix__ строка, например:

<!--
{{ item_forms.empty_form }}

{# <!-- or for crispy forms --> {% crispy item_forms.empty_form item_forms.form.helper %} #}
-->  

Итак, сначала мы должны заменить это __prefix__ по идентификатору и добавьте форму, используя этот шаблон.
Вот фрагмент кода шаблона формы, который мы можем использовать для создания новых элементов:

<script type="text/html" id="item-template">
<div id="item-__prefix__">
    {{ item_forms.empty_form }}
    <!-- crispy: {% crispy item_forms.empty_form item_forms.form.helper %} -->
</div>
</script>

Затем нам нужно отобразить основную часть формы:

<form action="" method="post">
{% csrf_token %}
{{ item_forms.management_form }}
<div id="items-form-container">
    {% for item_form in item_forms %}
        <div id="item-{{ forloop.counter0 }}">
            {{ item_form.id }}
            {{ item_form.as_p }}
            {# <!-- or for crispy forms --> {% crispy item_form %} #}
        </div>
    {% endfor %}
</div>
<a href="#" id="add-item-button" class="btn btn-info add-item">Add Item</a>
</form>

Наконец, нам нужно добавить JS (jquery, протестированный с 1.9.1 и 2.1.0), чтобы добавить следующую форму набора форм. Обратите внимание, мы не будем использовать underscore.js, так как в этом случае это не нужно: просто заменить str.replace __prefix__ по следующему номеру "id")

<script>
$(document).ready(function() {
    $('.add-item').click(function(ev) {
        ev.preventDefault();
        var count = $('#items-form-container').children().length;
        var tmplMarkup = $('#item-template').html();
        var compiledTmpl = tmplMarkup.replace(/__prefix__/g, count);
        $('div#items-form-container').append(compiledTmpl);

        // update form count
        $('#id_item_items-TOTAL_FORMS').attr('value', count+1);

        // some animate to scroll to view our new form
        $('html, body').animate({
                scrollTop: $("#add-item-button").position().top-200
            }, 800);
    });
});
</script>

Вот и все, просто нажмите кнопку "Добавить элемент", и появится новый элемент формы.

Обязательно замените этот образец своим именем приложения / модели.

Другие вопросы по тегам