最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

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

matteradmin4PV0评论

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

Post a comment

comment list (0)

  1. No comments so far