2013-02-21 46 views
0

在Django管理添加页面,使用TabularInline当它有一个锚Add another Poll它的HTML看起来像Django的管理员formset:如何使用jQuery添加一个新的formset行?

<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()不起作用? 或其他建议做同样的事情?

+0

我没有找到'addbtn.click()'的代码(你正在调用这个函数但没有执行)你有没有想要发布的东西? – kartheek 2013-02-21 07:59:20

+0

我认为在文档准备好之后,click()实现已经绑定到'addButton.click(...',当调用'$(rows).formset(...)'时,我所要做的就是触发click事件。我的想象力错了吗? – jcjason 2013-02-21 08:21:38

回答

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> 
0

addbtnaddButton是不同的对象,因此有不同的点击事件处理程序。您将不得不扩展addButton以添加其他事件处理程序。此外,绑定于DOM准备,如事件:

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

仅适用于那些当DOM被加载元素,并且将不被施加到选择器的未来元素。要做到这一点,你需要使用.live()

+0

谢谢,我会试一试 – jcjason 2013-02-22 04:47:02

+0

我有一些问题... 1.如果addbtn和addButton是不同的objs,为什么点击“a”会触发'addButton.click'? 2.我可以通过一些方法获得'addButton'对象吗? 3.如何扩展jQuery插件中的本地对象'addButton'? – jcjason 2013-03-01 10:14:53

+0

仔细检查选择器,它会出现有一些重叠,这可以解释为什么你在两个地方看到事件。不幸的是,我不像JavaScript那样精通,所以我不确定如何最好地扩展'addButton' – Brandon 2013-03-01 12:47:09