使用jQuery提交数组的动态HTML

时间:2012-02-02 03:06:43

标签: jquery forms

不太确定如何标题这个问题,但这是我遇到的问题:

我需要能够通过HTML表单提交数组或链接的数据列表。由于这个数组的长度可变,我有两个选择:

  1. 使用某种形式的分隔符(例如,列表中以逗号分隔的项目)
  2. 在需要添加新项目时动态生成多个输入(每个数组项目)
  3. 我想继续第二种选择,虽然我觉得由于这个特定项目会有很多这样的“数组输入”,我应该创建一个jQuery插件,这样我就可以更容易地将这个功能应用到未来的表单中。

    当我研究这个时,我也一直在为多种输入类型添加功能,选择,选择倍数(通过分隔符)和链接输入(例如 - 具有两个文本输入,用于“名字”和“姓氏” “必须作为一对提交”

    我有一个基本的布局,我认为它应该如何工作:

    (function($) { // Self-calling anonymous function to avoid namespace collisions or compatibility issues
    
        $.fn.dynamicList = function( options ) { // jQuery plugin definition
    
            /* Set up default options here */
            defaults = {
                option1: "value1",
                option2: "value2"
            };
            var options = $.extend( defaults, options );
    
            /* Step 1. Add a jQuery-UI plus icon to the DOM */
            /* Note: I have an option to specify where this icon should go in the DOM. It defaults right after the last input */
            plus = $("<span>").addClass( 'jquery-ui-classes' );
            this.last().after( plus );
    
            /* Step 2. Add a table to the DOM for displaying added values */
            /* Note: I have an option to specify where this table should go in the DOM. It defaults right after the plus icon */
            plus.after( table );
    
            /* Step 3. Add a handler for our plus button */
            this.delegate( plus, 'click', function() {
                /* Read the inputs, add their values to the table, empty the inputs */
                /* Also, the last column of the table contains a minus button */
                /* This is where I THOUGHT my first issue was.... */
                minus = $("<span>").addClass( 'jquery-ui-classes' );
                table.append( row ).append( minus );
            });
    
            /* Step 4. Add a handler for our minus button */
            /* Since the minus is created within the plus handler we can't use "minus" here */
            /* Instead I use a class name to locate it */
            this.delegate( '.jquery-ui-minus-class', 'click', function() {
                /* Remove the relevant row from the table */
                $(this).parents('tr').remove();
            });
    
            /* Step 5. Add our submit handler */
            this.parents('form').first().submit(function() {
                /* We want all of the data in the table to be submitted with the form */
                /* Therefore we create an input per cell and name it accordingly */
                /* The name is just the name of the original input plus "[]" to make it an array */
                /* This is where I thought my second problem was */
            });
    
            return this; // Maintain chain-ability
    
        };
    
    )(jQuery);
    

    在您希望用动态列表替换的输入上调用此代码。如果选择了多个输入,则它们将成为链接数据的列表(例如名字和姓氏示例)。如何调用它的示例如下:

    <html>
        <head>
            <!-- Include jQuery and my dynamic list library here -->
            <script>
                $('#fn,#ln').dynamicList();
            </script>
        </head>
        <body>
            <form>
                <input id="fn" name="first_name" />
                <input id="ln" name="last_name" />
            </form>
        </body>
    </html>
    

    这将创建一个动态列表,您可以在其中键入名字和姓氏,然后单击加号按钮(现在根据您的CSS规则在姓氏输入的右侧或下方),它将添加一行一个表,其中包含一列中的第一个名称,另一个列中的姓氏以及最后一个中的减号按钮。您可以继续输入名称并点击此加号按钮,表格无限向下延伸。在提交表格(通过提交按钮或任何其他方法)后,表格单元格应成为输入。

    我认为我遇到的第一个问题是在plus处理程序中。由于我在通过单击加号按钮调用的函数内部,因此“this”关键字现在引用加号图标的DOM元素。我无法获取输入的值以将它们添加到表中。我提出的一个解决方案是创建一个全局变量,它是调用动态列表函数的对象的副本,如下所示:

        .
        .
        .
            /* Step 2. Add a table to the DOM for displaying added values */
            /* Note: I have an option to specify where this table should go in the DOM. It defaults right after the plus icon */
            plus.after( table );
    
            var dynamicList = this;
    
            /* Step 3. Add a handler for our plus button */
            this.delegate( plus, 'click', function() {
                /* Read the inputs, add their values to the table, empty the inputs */
                /* Also, the last column of the table contains a minus button */
                /* This is where I THOUGHT my first issue was.... */
    
                for( i = 0; i < dynamicList.length; i++ ) {
                    // dynamicList.get(i) will give us each input in order
                }
    
                minus = $("<span>").addClass( 'jquery-ui-classes' );
                table.append( row ).append( minus );
            });
        .
        .
        .
    

    我对此的关注是,如果我实例化多个动态列表,它们将相互覆盖。这是真的?如果是这样,我该如何克服这个?

    我认为我遇到的第二个问题是类似的。提交表单后,我需要找到表格以获取要提交的值并找到输入,以便获取应提交的名称。

    然而,在使用代码尝试自己修复它时,我遇到的问题比预期的要快得多。

    Uncaught TypeError: Object [object Object] has no method 'replace'
    jquery-1.6.2.min.js:16
    f.each.f.fn.(anonymous function)     jquery-1.6.2.min.js:17
    f.fn.extend.delegate     jquery-1.6.2.min.js:17
    $.fn.dynamicList     jquery.dynamicList.js:76
    (anonymous function)      test.php:16
    f.extend._Deferred.e.resolveWith     jquery-1.6.2.min.js:16
    e.extend.ready     jquery-1.6.2.min.js:16
    c.addEventListener.B     jquery-1.6.2.min.js:16
    

    查看我的动态列表代码的第76行,它是以下行:

    this.delegate( plus, 'click', function() {
    

    我可以不调用.delegate(),因为“this”指的是多个jQuery对象吗?或者我可以不调用.delegate()因为“this”不是加号图标的父元素吗?一旦这个问题得到解决,我该如何解决其他两个问题?

    编辑 -

    我修改了标题,我在76行找到了解决问题的方法。我不确定.delegate()到底是怎么回事,因为起初我试过了:

    this.first().parent().delegate( plus, 'click', function() {
    

    它仍然对我不满。然后我意识到我可以使用.click()函数代替(我有点蠢)

    plus.click( function() {
    

    我在每行创建减号按钮时使用了类似的逻辑。我在创建减号按钮之后和插入DOM之前添加了minus.click(),省去了在代码中的任何位置使用.delegate()的麻烦。

    仍然不确定如何从plus处理程序中的输入字段中获取值,因为此时“this”关键字已被覆盖以引用加号按钮,而不是我的输入字段。

1 个答案:

答案 0 :(得分:1)

  

我修改了标题,我在第76行找到了解决问题的方法。我不确定.delegate()是如何工作的,因为起初我试过了:

this.first().parent().delegate( plus, 'click', function() {
  

它仍然对我不满。然后我意识到我可以使用.click()函数代替(我有点蠢)

plus.click( function() {
  

我在每行创建减号按钮时使用了类似的逻辑。我在创建减号按钮之后和插入DOM之前添加了minus.click(),省去了在代码中任何地方使用.delegate()的麻烦。