最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Using jQuery to Clone Multiple Form Elements Within Separate Divs - Stack Overflow

programmeradmin2浏览0评论

I am using the following script to clone a div with form elements inside; however, it currently adding sequential numbers (1, 2, 3) to the container div id correctly, but then is adding a "name2" and "name3" to the sub-divs in the clone, instead of to the actual form elements.

Example of problem:

<div class="clonedInput" id="container1">
    <div>First Name:
        <input type="text" id="first_name1" name="first_name1">
    </div>
    <div>Last Name:
        <input type="text" id="last_name1" name="last_name1">
    </div>
    <div>Phone:
        <input type="text" id="phone1" name="phone1">
    </div>
</div>

<div class="clonedInput" id="container2">
    <div id="name2" name="name2">First Name:
        <input type="text" id="first_name1" name="first_name1">
    </div>
    <div>Last Name:
        <input type="text" id="last_name1" name="last_name1">
    </div>
    <div>Phone:
        <input type="text" id="phone1" name="phone1">
    </div>
</div>

<div class="clonedInput" id="container3">
    <div id="name3" name="name3">First Name:
        <input type="text" id="first_name1" name="first_name1">
    </div>
    <div>Last Name:
        <input type="text" id="last_name1" name="last_name1">
    </div>
    <div>Phone:
        <input type="text" id="phone1" name="phone1">
    </div>
</div>

Full code:

<html>
<head>
<title></title>
<script src=".3/jquery.min.js"></script>
<script type="text/javascript">
jQuery( function ( $ ) {
    $( '#btnAdd' ).click( function() {
        var num = $( '.clonedInput' ).length;      // how many "duplicatable" input fields we currently have
        var newNum  = new Number( num + 1 );        // the numeric ID of the new input field being added
        var newElem = $( '#container' + num ).clone().attr( 'id', 'container' + newNum );

        newElem.children( ':first' ).attr( 'id', 'name' + newNum ).attr( 'name', 'name' + newNum );
        $( '#container' + num ).after( newElem );
        $( '#btnDel' ).attr( 'disabled', false );
        if ( newNum == 25 )
            $( '#btnAdd' ).attr( 'disabled', 'disabled' );
    });

    $( '#btnDel' ).click( function() {
        var num = $( '.clonedInput' ).length;      // how many "duplicatable" input fields we currently have
        $( '#container' + num ).remove();              // remove the last element
        $( '#btnAdd' ).attr( 'disabled', false );  // enable the "add" button

        // if only one element remains, disable the "remove" button
        if ( num-1 == 1 )
            $( '#btnDel' ).attr( 'disabled', 'disabled' );
    });

    $( '#btnDel' ).attr( 'disabled', 'disabled' );
});
        </script>
</head>

<body>
<form id="myForm">
    <div id="container1" class="clonedInput"> 
        <div>
        First Name:
        <input type="text" name="first_name1" id="first_name1">
        </div>
        <div>
        Last Name:
        <input type="text" name="last_name1" id="last_name1">
        </div>
        <div>
        Phone:
        <input type="text" name="phone1" id="phone1">
        </div>
    </div>
    <div>
        <input type="button" id="btnAdd" value="add another name" />
        <input type="button" id="btnDel" value="remove name" />
    </div>
</form>
</body>
</html>

I am using the following script to clone a div with form elements inside; however, it currently adding sequential numbers (1, 2, 3) to the container div id correctly, but then is adding a "name2" and "name3" to the sub-divs in the clone, instead of to the actual form elements.

Example of problem:

<div class="clonedInput" id="container1">
    <div>First Name:
        <input type="text" id="first_name1" name="first_name1">
    </div>
    <div>Last Name:
        <input type="text" id="last_name1" name="last_name1">
    </div>
    <div>Phone:
        <input type="text" id="phone1" name="phone1">
    </div>
</div>

<div class="clonedInput" id="container2">
    <div id="name2" name="name2">First Name:
        <input type="text" id="first_name1" name="first_name1">
    </div>
    <div>Last Name:
        <input type="text" id="last_name1" name="last_name1">
    </div>
    <div>Phone:
        <input type="text" id="phone1" name="phone1">
    </div>
</div>

<div class="clonedInput" id="container3">
    <div id="name3" name="name3">First Name:
        <input type="text" id="first_name1" name="first_name1">
    </div>
    <div>Last Name:
        <input type="text" id="last_name1" name="last_name1">
    </div>
    <div>Phone:
        <input type="text" id="phone1" name="phone1">
    </div>
</div>

Full code:

<html>
<head>
<title></title>
<script src="http://ajax.googleapis./ajax/libs/jquery/1.3/jquery.min.js"></script>
<script type="text/javascript">
jQuery( function ( $ ) {
    $( '#btnAdd' ).click( function() {
        var num = $( '.clonedInput' ).length;      // how many "duplicatable" input fields we currently have
        var newNum  = new Number( num + 1 );        // the numeric ID of the new input field being added
        var newElem = $( '#container' + num ).clone().attr( 'id', 'container' + newNum );

        newElem.children( ':first' ).attr( 'id', 'name' + newNum ).attr( 'name', 'name' + newNum );
        $( '#container' + num ).after( newElem );
        $( '#btnDel' ).attr( 'disabled', false );
        if ( newNum == 25 )
            $( '#btnAdd' ).attr( 'disabled', 'disabled' );
    });

    $( '#btnDel' ).click( function() {
        var num = $( '.clonedInput' ).length;      // how many "duplicatable" input fields we currently have
        $( '#container' + num ).remove();              // remove the last element
        $( '#btnAdd' ).attr( 'disabled', false );  // enable the "add" button

        // if only one element remains, disable the "remove" button
        if ( num-1 == 1 )
            $( '#btnDel' ).attr( 'disabled', 'disabled' );
    });

    $( '#btnDel' ).attr( 'disabled', 'disabled' );
});
        </script>
</head>

<body>
<form id="myForm">
    <div id="container1" class="clonedInput"> 
        <div>
        First Name:
        <input type="text" name="first_name1" id="first_name1">
        </div>
        <div>
        Last Name:
        <input type="text" name="last_name1" id="last_name1">
        </div>
        <div>
        Phone:
        <input type="text" name="phone1" id="phone1">
        </div>
    </div>
    <div>
        <input type="button" id="btnAdd" value="add another name" />
        <input type="button" id="btnDel" value="remove name" />
    </div>
</form>
</body>
</html>
Share Improve this question edited Nov 12, 2011 at 14:21 Michael asked Nov 7, 2011 at 2:36 MichaelMichael 2,29415 gold badges49 silver badges80 bronze badges 1
  • It seems you're only changing first child with newElem.children( ':first' ) – Doug Owings Commented Nov 7, 2011 at 2:43
Add a ment  | 

4 Answers 4

Reset to default 1

The problem is this line here:

newElem.children( ':first' ).attr( 'id', 'name' + newNum ).attr( 'name', 'name' + newNum );

Only the first child of each newElem is being selected, which is why only the first input element is being changed. What you want to do is select ALL the children that are input elements. Try this:

newElement.children('input').attr('id',$(this).attr('id') + newNum).attr('name',$(this).attr('name') + newNum);
var cloneEl = (function () {
    var counter = 1;

    return function cloneEl(id) {
        var el = document.getElementById("container");
        var clone = el.cloneNode(true);

        clone.id = el.id+counter;
        [].forEach.call(clone.children, function (node, key) {
             var oldNode = el.children[key];
             node.id = oldNode.id+counter;
             node.name = oldNode.id+counter;
        });

        counter++;
        return clone;
    };
})(); 

Live Example

Here's what I do: if you have multiple layers of div, tables (like me), you have to change the code provided by Brian Glaz from newElem.children to newElem.find. Here is his fiddle: http://jsfiddle/B7bgN/10/

All I did was change one word. From children to find. (Children will only traverse one level while find will get descendants of each element.

http://jsfiddle/the7th/sSS3c/1/

$(document).ready(function () {
                                    var newNum = 1;
                                    cloneMe = function (el) {
                                        var newElem = el.clone().attr('class', 'firstrow' + newNum).insertAfter(".firstrow0");

                                        newElem.find('input').each(function (index, elem) {
                                            $(elem).attr('id', $(elem).attr('id') + newNum).attr('name', $(elem).attr('name') + newNum);
                                        });
                                        if (newNum == 2) {
                                            $("#cloneb").hide();
                                        };
                                        newNum++;
                                    };
                                });

Though not a solution to the OP question, I found Jquery Form Clone Plugin to be quite helpful. Its has everything preset, index, nested forms, controls and even callbacks like beforeAdd, after add etc. I mentioned it because when searching for a jQuery's solution, I ended up here. So I thought it might help others searching for jQuery's solution for cloning forms

发布评论

评论列表(0)

  1. 暂无评论