Django admin formset:如何使用jQuery添加一行新的formset?

时间:2013-02-21 07:35:09

标签: jquery django django-forms django-admin

在django管理员添加页面中,当使用TabularInline时,它有一个锚Add another Poll,其html看起来像

<a href="javascript:void(0)">Add another Poll</a>

现在我想添加一个新行,就像在触发文件输入更改事件时在锚点上使用鼠标点击一样:

$('input:file').change(function(e){
    //... do something ...
    var rows = "#poll_set-group .tabular.inline-related tbody tr";
    var addbtn = $(rows).parent().find("tr:last a")
    addbtn.click(); // try to add a new row but doesn't work
});

元素选择正确但click()不起作用。我也试过了addbtn.trigger('click')虽然它几乎做了同样的事情但仍然无效。

当我追踪到Django的inline.js时,可以看到绑定函数

inline.js

(function($) {
    $.fn.formset = function(opts) {
        ///...
        if ($(this).length && showAddButton) {
            var addButton;
            if ($(this).attr("tagName") == "TR") {
                //...
                addButton = $(this).parent().find("tr:last a");
            } else {
                //...
                addButton = $(this).filter(":last").next().find("a");
            }
            addButton.click(function() {
            //...
            });
        } 
    }
})(django.jQuery);

有谁可以告诉我为什么.click()不起作用? 或任何其他建议做同样的事情?

2 个答案:

答案 0 :(得分:2)

经过几个小时的努力,我发现了如何做到这一点,并在过程中学到了一些关键点。

1.使用.data在插件中存储本地对象。 (不确定是否会导致内存泄漏或任何其他问题)

inline.js
(function($) {
    $.fn.formset = function(opts) {
        ///...
        if ($(this).length && showAddButton) {
            var addButton;
            if ($(this).attr("tagName") == "TR") {
                //...
                addButton = $(this).parent().find("tr:last a");
            } else {
                //...
                addButton = $(this).filter(":last").next().find("a");
            }

            // store local object 'addButton' into data()
            var $this = $(this), data = $this.data('addButton')
            if( !data ){
                $this.data('addButton', {
                    target : addButton,
                });
            }

            addButton.click(function() {
            //...
            });
        } 
    }
})(django.jQuery);

2.jQuery对象实例存在于其自己的命名空间中(本例中为django.jQuery)

<script type="text/javascript">
$(document).ready(function(){
    (function($) {
        var rows1 = "#poll_set-group .tabular.inline-related tbody tr";
        $(rows1).formest({...});
    })(django.jQuery);

    var rows2 = "#poll_set-group .tabular.inline-related tbody tr";
    $(rows2).data('addButton')
    // Error, rows2's data is empty
    // cause of although rows1 & rows2 have same selector, but they are different objects in the different namespaces

    // use django.jQuery(rows2) to get the same object instance of rows1
    // this can trigger the same event handler being bound in the plugin inline.js
    django.jQuery(rows2).data('addButton').target.click(); 
});
</script>

答案 1 :(得分:0)

addbtnaddButton是不同的对象,因此具有不同的点击事件处理程序。您必须扩展addButton以添加其他事件处理程序。此外,已准备好绑定在DOM上的事件,例如:

$('input:file).change();

仅适用于加载DOM时存在的元素,并且不会应用于该选择器的未来元素。为此,您需要使用.live()