三生石@ 2009-02-01 22:26 采纳率: 100%
浏览 255
已采纳

使用 Ajax 动态地向 Django 格式集添加表单

I want to automatically add new forms to a Django formset using Ajax, so that when the user clicks an "add" button it runs JavaScript that adds a new form (which is part of the formset) to the page.

转载于:https://stackoverflow.com/questions/501719/dynamically-adding-a-form-to-a-django-formset-with-ajax

  • 写回答

15条回答 默认 最新

  • ~Onlooker 2009-03-21 20:58
    关注

    This is how I do it, using jQuery:

    My template:

    <h3>My Services</h3>
    {{ serviceFormset.management_form }}
    {% for form in serviceFormset.forms %}
        <div class='table'>
        <table class='no_error'>
            {{ form.as_table }}
        </table>
        </div>
    {% endfor %}
    <input type="button" value="Add More" id="add_more">
    <script>
        $('#add_more').click(function() {
            cloneMore('div.table:last', 'service');
        });
    </script>
    

    In a javascript file:

    function cloneMore(selector, type) {
        var newElement = $(selector).clone(true);
        var total = $('#id_' + type + '-TOTAL_FORMS').val();
        newElement.find(':input').each(function() {
            var name = $(this).attr('name').replace('-' + (total-1) + '-','-' + total + '-');
            var id = 'id_' + name;
            $(this).attr({'name': name, 'id': id}).val('').removeAttr('checked');
        });
        newElement.find('label').each(function() {
            var newFor = $(this).attr('for').replace('-' + (total-1) + '-','-' + total + '-');
            $(this).attr('for', newFor);
        });
        total++;
        $('#id_' + type + '-TOTAL_FORMS').val(total);
        $(selector).after(newElement);
    }
    

    What it does:

    cloneMore accepts selector as the first argument, and the type of formset as the 2nd one. What the selector should do is pass it what it should duplicate. In this case, I pass it div.table:last so that jQuery looks for the last table with a class of table. The :last part of it is important because the selector is also used to determine what the new form will be inserted after. More than likely you'd want it at the end of the rest of the forms. The type argument is so that we can update the management_form field, notably TOTAL_FORMS, as well as the actual form fields. If you have a formset full of, say, Client models, the management fields will have IDs of id_clients-TOTAL_FORMS and id_clients-INITIAL_FORMS, while the form fields will be in a format of id_clients-N-fieldname with N being the form number, starting with 0. So with the type argument the cloneMore function looks at how many forms there currently are, and goes through every input and label inside the new form replacing all the field names/ids from something like id_clients-(N)-name to id_clients-(N+1)-name and so on. After it is finished, it updates the TOTAL_FORMS field to reflect the new form and adds it to the end of the set.

    This function is particularly helpful to me because the way it is setup it allows me to use it throughout the app when I want to provide more forms in a formset, and doesn't make me need to have a hidden "template" form to duplicate as long as I pass it the formset name and the format in which the forms are laid out. Hope it helps.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(14条)

报告相同问题?

悬赏问题

  • ¥20 蓝牙耳机怎么查看日志
  • ¥15 Fluent齿轮搅油
  • ¥15 八爪鱼爬数据为什么自己停了
  • ¥15 交替优化波束形成和ris反射角使保密速率最大化
  • ¥15 树莓派与pix飞控通信
  • ¥15 自动转发微信群信息到另外一个微信群
  • ¥15 outlook无法配置成功
  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏