我如何用jQuery复制表单元素和它们里面的数据


How would I duplicate form elements AND the data inside them with jQuery?

查看此表格- 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开始编号。我想过使用选择器来找到最高数量的网站,并在该数字上开始变量"网站",但我不确定如何。对于如何做到这一点,或者整体上更好的系统,任何建议都将不胜感激。

您希望遍历siteform中的输入字段,并使用它们的name属性作为键将它们存储在对象中。

然后在复制您创建的对象之后,在新的复制表单中查找相应的字段并设置它们的值。

像这样的东西(没有测试,只是想法)

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/

您可以考虑使用cloneNode来真正克隆之前的site-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 确实有自己的clone()方法(我不太使用jQuery,所以我不知道,在回答之前我也没有费心去检查)。使用jQuery的方法可能比使用内置的cloneNode DOM方法更好,因为您已经在使用jQuery作为事件侦听器。我已经更新了代码

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

$("#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);
}

好了,我终于想通了。这或多或少是对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);
        });

为了可读性,我使用了额外的变量,但如果您不这样做,直接使用这些方法,它应该做得很好。

别忘了创建一个函数来注册事件!这是非常重要的,因为当加载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>