在表单中的formset中添加和删除行

时间:2017-11-09 15:40:00

标签: jquery django twitter-bootstrap django-forms django-crispy-forms

我在使用Djangodjango-crispy-forms构建的表单中有一个bootstrap 4.0.0-alpha.6表单集。它看起来像这样:

{% block content %}
    <div>
        <h1 class="text-center">Create New Activity</h1>
        <div class="row">
            <div class="col"></div>
            <div class="col-md-8 col-lg-8">
                <form role="form" method="post">
                    {% csrf_token %}
                    {{ form|crispy }}
                    {{ activitykeycharacteristics_formset|crispy }}
                    <hr>
                    <button class="primaryAction btn btn-primary pull-right ml-1" type="submit">{% trans "Submit" %}</button>
                    <a class="btn btn-secondary pull-right" href="{{ request.META.HTTP_REFERER }}" role="button">{% trans "Cancel" %}</a>
                </form>
            </div>
            <div class="col"></div>
        </div>
    </div>
{% endblock content %}

我一直在尝试做的是添加和删除按钮,以便我可以添加或删除formset中的表单。目前它在formset中使用一个表单进行渲染,因此只能看到一个添加按钮,但是一旦有多个删除按钮也应该被看到。

我非常确定最好的方法是使用jQuery添加和删除表单,但我还没有能够让它正常工作。我认为我在这个SO question中使用Dave的答案使用了添加按钮。但我无法正确更新输入的索引。我无法在那个问题上得到公认的答案,而且我不确定原因。

formset中的表单由两个django-autocomplete-light下拉列表组成。

如果有人能帮助我,我会非常感激。

感谢您的时间。

- UPDATE -

以下是带有更新模板的js代码:

js file:

function updateElementIndex(el, prefix, ndx) {
    let id_regex = new RegExp('(' + prefix + '-\\d+)');
    let replacement = prefix + '-' + ndx;
    if ($(el).attr("for")) $(el).attr("for", $(el).attr("for").replace(id_regex, replacement));
    if (el.id) el.id = el.id.replace(id_regex, replacement);
    if (el.key_characteristic) el.key_characteristic = el.key_characteristic.replace(id_regex, replacement);
    if (el.data_type) el.data_type = el.data_type.replace(id_regex, replacement);
}

function cloneMore(selector, prefix) {
    let newElement = $(selector).clone(true);
    let total = $('#id_' + prefix + '-TOTAL_FORMS').val();
    newElement.find(':input').each(function() {
        // Not sure how to adapt this to work with two inputs
        let id;
        let key_characteristic = $(this).attr('key_characteristic');
        let data_type = $(this).attr('data_type');
        if (key_characteristic) {
            key_characteristic.replace('-' + (total-1) + '-', '-' + total + '-');
            id = 'id_' + key_characteristic;
        } else if (data_type) {
            data_type.replace('-' + (total-1) + '-', '-' + total + '-');
            id = 'id_' + data_type;
        }
        $(this).attr({'key_characteristic': key_characteristic, 'data_type': data_type, 'id': id}).val('').removeAttr('checked');
    });
    total++;
    $('#id_' + prefix + '-TOTAL_FORMS').val(total);
    $(selector).after(newElement);
}

function deleteForm(prefix, btn) {
    let total = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
    if (total > 1){
        btn.closest('#formset').remove();
        let forms = $('#formset');
        $('#id_' + prefix + '-TOTAL_FORMS').val(forms.length);
        for (let i=0, formCount=forms.length; i<formCount; i++) {
            $(forms.get(i)).find(':input').each(function() {
                updateElementIndex(this, prefix, i);
            });
        }
    }
}

$('#add-form').on('click', function(e) {
    e.preventDefault();
    cloneMore('#formset:last', 'form');
});

$('#remove-form').on('click', function(e) {
    e.preventDefault();
    deleteForm('form', $(this));
});

更新的模板:

{% block content %}
    <div>
        <h1 class="text-center">Create New Activity</h1>
        <div class="row">
            <div class="col"></div>
            <div class="col-md-8 col-lg-8">
                <form role="form" method="post">
                    {% csrf_token %}
                    {{ form|crispy }}
                    <div id="formset">
                        {{ activitykeycharacteristics_formset.management_form }}
                        {% for form in activitykeycharacteristics_formset.forms %}
                            {{ form|crispy }}
                            {% if forloop.counter != 1 %}
                                <button class="btn btn-primary" id="add-form"><i class="fa fa-plus"></i></button>
                                <button class="btn btn-danger" id="remove-form"><i class="fa fa-minus"></i></button>
                            {% else %}
                                <button class="btn btn-primary" id="add-form"><i class="fa fa-plus"></i></button>
                            {% endif %}
                        {% endfor %}
                    </div>
{#                    {{ activitykeycharacteristics_formset|crispy }}#}
                    <hr>
                    <button class="primaryAction btn btn-primary pull-right ml-1" type="submit">{% trans "Submit" %}</button>
                    <a class="btn btn-secondary pull-right" href="{{ request.META.HTTP_REFERER }}" role="button">{% trans "Cancel" %}</a>
                </form>
            </div>
            <div class="col"></div>
        </div>
    </div>
{% endblock content %}

0 个答案:

没有答案