[PYTHON] Dynamically add form fields in Django

Introduction

I'm a third year college student studying programming on my own.

Previously, when I created a web application in PHP, I used to [dynamically add form input fields] Qiita. I'm currently migrating my web app to Django, but I've had a hard time solving the title issue, so I'll leave it here.

Only this was written in the documentation ...

empty_form BaseFormSet provides an additional attribute empty_form which returns a form instance with a prefix of prefix for easier use in dynamic forms with JavaScript.

I try to keep the code as concise as possible so that even beginners can easily understand it.

Previous article

If you're not sure from this article alone, you may find it helpful to look at previous articles.

-[Dynamic addition of form input field] Qiita -CodePen CodePen(You can check the operation.)

code

If you want Django to handle forms dynamically, use ** empty_form ** from Formsets.

An id such as ʻid_form-{No.}-place_name is automatically inserted into ʻinput of a general form generated by Django. However, if ** empty_form ** is used, the id of all ʻinput will be ʻid_form-__ plefix__-place_name, so it is necessary to replace the __plefix__ part with a number.

template.html


<form method="POST" id="form">
    {% csrf_token %}
    {{ form.management_form }}
    <div class="text">
        {{ form.empty_form.as_p }}
    </div>
    <button type="button" id="btn-clone">clone</button>
    <button type="submit">submit</button>
</form>

In reality, it looks like this.

template.html


<form method="POST" id="form">
    <!-- ...... -->
    <input type="hidden" name="form-TOTAL_FORMS" value="2" id="id_form-TOTAL_FORMS">
    <!-- ...... -->
    <div class="text">
        <p>
            <label for="id_form-__prefix__-place_name">Input:</label>
            <input type="text" name="form-__prefix__-place_name" id="id_form-__prefix__-place_name">
            <input type="hidden" name="form-__prefix__-id" id="id_form-__prefix__-id">
        </p>
    </div>
    <button type="button" id="btn-clone">clone</button>
    <button type="submit">submit</button>
</form>

Rewrite __prefix__. Also, specify the number of ʻinput with the value of ʻinput [id =" id_form-TOTAL_FORMS "].

script.js


$(function() {


    // clone
    $('#btn-clone').click(function() {
        var text = $('.text').last();  //Input at the end
        clone = text.clone().insertAfter(text);  //Add input to the end
        clone.find("input[type='text']").val('');  //value is also cloned so delete it
    });


    //Operate id etc. for Django from here
    $('#form').submit(function() {  //Just before submitting the form

        //Specify the number of input fields on the form
        const text = $('.text');
        $('[name=form-TOTAL_FORMS]').val(text.length);

        //In each input field__prefix__With index
        text.each(function(index, element){
            html = $(element).html().replace(/__prefix__/g, index);
            value = $(element).find("input[type='text']").val();  //Save the value as it disappears
            $(element).html(html);
            $(element).find("input[type='text']").val(value);
        });

    });
});

If you want to implement the form deletion function, see [Previous article] Qiita. I've only implemented adding forms here for clarity. The code is redundant because it is supposed to finally implement the form deletion function. If you do not need the form delete function, please correct it.

reference

-[Create a Django form class with a dynamic number of fields (it-swarm.dev)](https://www.it-swarm.dev/ja/python/%E5%8B%95%E7%9A % 84% E3% 81% AA% E3% 83% 95% E3% 82% A3% E3% 83% BC% E3% 83% AB% E3% 83% 89% E6% 95% B0% E3% 82% 92 % E6% 8C% 81% E3% 81% A4django% E3% 83% 95% E3% 82% A9% E3% 83% BC% E3% 83% A0% E3% 82% AF% E3% 83% A9% E3 % 82% B9% E3% 82% 92% E4% BD% 9C% E6% 88% 90% E3% 81% 99% E3% 82% 8B / 971177164 /)

-Add dynamic forms to django formset using javascript in the right way (stackoverrun)

Recommended Posts

Dynamically add form fields in Django
Implementing Add Form Buttons in Django Inline Forms Set Part2
Implement an add form button in your Django inline form set
Dynamically specify a ModelChoiceField queryset in Django
Django Contact Form 2
Models in Django
Django Suggested Form
Django Form Gleaning
Forms in Django
Django contact form
Save multiple models in one form with Django
Set the form DateField to type = date in Django
Submit in [Python] form
Model changes in Django
Dynamically create tables in schema with Django, dynamically generate models
Best practices for dynamically handling LINE Flex Messages in Django
Performance optimization in Django 3.xx
Dynamically set env.hosts in fabric
PHP var_dump in Django templates
Handle constants in Django templates
Rename table columns in Django3
Output table structure in Django
(Note) Django in Vagrant environment
Dynamically call methods in Python
Show Django ManyToManyField in Template
django-rest-framework Dynamically change serializer fields