如何使用 jQuery 复制表单元素和其中的数据?

Posted

技术标签:

【中文标题】如何使用 jQuery 复制表单元素和其中的数据?【英文标题】:How would I duplicate form elements AND the data inside them with jQuery? 【发布时间】:2011-10-27 15:49:53 【问题描述】:

查看此表格 - http://schnell.dreamhosters.com/form.php

此表单有一部分供您输入数据,您可以通过单击一个名为“添加站点”的按钮来选择添加更多相同的数据,它将使该部分的另一个进入另一个站点。这是执行复制的 jQuery...

$(function ()   
    var sites = 1;
    var siteform = $("#site1").html();

    $(".addsites").live("click", function(e) 
        e.preventDefault();
        sites++;
        $("#events").append("<div id='site" + sites + "'>"
            + "<br /><hr><br />"
            + siteform
            + "<center><button class='removesites' title='site"
            + sites + "'>Remove This Site</button><br />"
            + "<button class='addsites'>Add Another Site</button>"
            + "</center></div>");           
    );

    $(".removesites").live("click", function(e) 
        e.preventDefault();
        var id = $(this).attr("title");
        $("#" + id).remove();
    );     
);

复制工作完美,但让我烦恼的一件事是,当我必须为声称拥有很多网站的人输入数据时,不得不重复表单这一部分的相同或相似部分(就像每个网站在同一个城市,同一天,由同一个人等)所以我的想法是,每次重复时,表单元素的值也会延续,我只是编辑不一样的部分。当前的实现只复制元素,而不是数据。我不知道如何轻松地将数据复制到新的部分,而且我找不到任何 jQuery 工具来做到这一点。

PS - 这部分并不那么重要,但我也考虑过使用相同的表单来加载数据以进行查看/编辑等。唯一的问题是重新打印表单意味着会有一个带有 id "Site7" 或其他东西的表单部分,但 jQuery 总是从 1 开始编号。我考虑过使用选择器来查找最高编号的站点并以该编号开始变量“站点”,但我不确定如何。任何建议如何做到这一点,或整体上更好的系统,将不胜感激。

【问题讨论】:

文档中的 .clone() 读起来像是您可能需要的? 【参考方案1】:

别忘了创建一个函数来注册事件!它非常重要,因为在加载 DOM 时,所有新属性都需要注册到 DOM。

小例子:

<script>
    $(document).ready(function()
        $('#click-me').click(function()
            registerClickEvent();
        )

        function registerClickEvent()
            $('<input type="text" name="input_field_example[]">').appendTo('#the-div-you-want')
        

        registerClickEvent();
    )
</script>

【讨论】:

【参考方案2】:

好吧,我终于想通了。这或多或少是对 Alex Pakka 答案的扩展。

        sites++;
        $("#events").append("<div id='site" + sites + "'>"
            + "<hr><br />"
            + siteform
            + "<center><button class='removesites' title='site"
            + sites + "'>Remove This Site</button><br />");
        $("#site1").find("input:checked, input:text, textarea, select").each(function() 
            var name = $(this).attr("name");
            var val = $(this).val();
            var checked = $(this).attr("checked");
            var selected = $(this).attr("selectedIndex");

            $('#site' + sites + ' [name="'+name+'"]').val(val);
            $('#site' + sites + ' [name="'+name+'"]').attr("checked", checked);
            $('#site' + sites + ' [name="'+name+'"]').attr("selectedIndex", selected);
        );

为了便于阅读,我使用了额外的 var,但如果你没有直接使用这些方法,它应该也能正常工作。

【讨论】:

【参考方案3】:

您可以考虑使用cloneNode 真正克隆以前的站点div 和(通过将true 传递给cloneNode)它的所有后代及其属性。只要知道克隆将具有与原始相同的id,因此您必须在之后手动设置其 id

在你的点击功能中试试这个

var clone = $("#site" + sites).clone(true, true); // clone the last div
sites++; // increment the number of divs
clone.attr('id', "site" + sites); // give the clone a unique id
$("#events").append(clone); // append it to the container

正如 Scuzzy 在评论中指出的那样,jQuery does 有自己的 clone() 方法(我不怎么使用 jQuery,所以我不知道,也懒得去检查在回答之前)。使用 jQuery 的方法可能比内置的 cloneNode DOM 方法更好,因为您已经将 jQuery 用于事件侦听器。我已经更新了代码

【讨论】:

好的,克隆工作正常,我想做的事。现在唯一的问题是,由于某种原因,该部分不会重复多次。 [b]编辑 - 修复它。现在一切都好。[/b] 刚刚注意到克隆不会复制下拉列表和文本区域的值。文档中没有提到它。 @MathiasSchnell:你试过.clone(true, true);吗?根据 jQuery 文档,这应该完全复制整个层次结构。我在编辑答案时忘记了第二个true。再说一次,我不是 jQuery 专家,但我认为它会起作用 是的,已经尝试过.clone(true, true)。此外,id 最初设置不正确,但我用clone.attr("id", "site" + sites); 修复了它 @MathiasSchnell:嗯......好吧,我不能告诉你为什么它没有按应有的方式复制所有内容(但也许你可以在这里使用其他一些答案来解决这个问题)。 id 是我的错误 - 我应该意识到 clone() 返回一个 jQuery 包装对象,而不是实际元素,所以使用 attr 是正确的解决方案【参考方案4】:

传递值的查询非常简单(请检查表单上所有正确类型的选择器):

$("#site1").find("input[checked], input:text, input:hidden, input:password, input:submit, option:selected, textarea")
            //.filter(":disabled")
            .each(function()

   $('#site2 [name="'+this.name+'"]').val(this.value);

【讨论】:

部分有效。选择列表和复选框不会被复制。【参考方案5】:

您希望遍历站点表单中的输入字段并将它们存储在一个对象中,使用它们的名称属性作为键。

然后在复制您制作的对象后,在新的复制表单中查找等效字段并设置它们的值。

类似这样的东西(未经测试,只是想法)

var obj = new Object();

$("#site1 input").each(function()
    obj[this.id] = this.value;
);

// Dupicate form

$.each(obj, function(key, value)
    $('#newform input[name="'+key+'"]').value = value;
);

请注意,这两个 each() 函数彼此不同。

http://api.jquery.com/jQuery.each/ http://api.jquery.com/each/

【讨论】:

以上是关于如何使用 jQuery 复制表单元素和其中的数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何从动态元素发布表单

如何通过jquery将表单数据与图像一起传递? [复制]

如何动态添加带有引导表单元素的 div?

如果输入元素是数组,如何使用 JQuery 发送序列化表单数据

Jquery学习笔记:操作form表单元素之一(文本框和下拉框)

如何使用 Jquery 添加/删除表单元素