Использование jQuery для клонирования нескольких элементов формы в отдельных подразделениях

#javascript #jquery #forms #clone

#javascript #jquery #формы #клонирование

Вопрос:

Я использую следующий скрипт для клонирования div с элементами формы внутри; однако в настоящее время он правильно добавляет порядковые номера (1, 2, 3) к идентификатору контейнера div, но затем добавляет «name2» и «name3» к подразделам в клоне, а не к фактическим элементам формы.

Пример проблемы:

 <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>
  

Полный код:

 <html>
<head>
<title></title>
<script src="http://ajax.googleapis.com/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>
  

Комментарии:

1. Кажется, вы меняете только первого дочернего элемента с newElem.children( ':first' )

Ответ №1:

Проблема в этой строке здесь:

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

Выбирается только первый дочерний элемент каждого newElem , поэтому изменяется только первый элемент ввода. Что вы хотите сделать, это выбрать ВСЕ дочерние элементы, которые являются элементами ввода. Попробуйте это:

 newElement.children('input').attr('id',$(this).attr('id')   newNum).attr('name',$(this).attr('name')   newNum);
  

Комментарии:

1. Вы действительно ожидаете, $(this).attr('id') что это сработает? Хороший вариант для ввода дубликатов идентификаторов в DOM, создания способа повреждения состояния.

2. @Raynos Да? о чем вы говорите? Опубликованный мной код ничего не вставляет в DOM. newNum добавляется к каждому идентификатору, чтобы сделать их уникальными. Вот упрощенный пример. http://jsfiddle.net/B7bgN/2 /

3. Вы вообще смотрели на идентификаторы входных данных в вашем примере? Как уже упоминалось, вы ввели дублирующиеся идентификаторы в DOM.

4. @Raynos новая рабочая скрипка http://jsfiddle.net/B7bgN/10 /

5. @BrianGlaz кажется, что ваша скрипка работает, но мне трудно экстраполировать это на мой текущий код. Вы можете помочь?

Ответ №2:

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

Живой пример

Ответ №3:

Вот что я делаю: если у вас есть несколько уровней div, таблиц (как у меня), вам нужно изменить код, предоставленный Брайаном Глазом, с newElem.children на newElem.find. Вот его скрипка:http://jsfiddle.net/B7bgN/10 /

Все, что я сделал, это изменил одно слово. Из дочерних элементов для поиска. (Дочерние элементы будут проходить только один уровень, в то время как find получит потомков каждого элемента.

http://jsfiddle.net/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  ;
                                    };
                                });
  

Ответ №4:

Хотя это и не решение вопроса OP, я обнаружил, что плагин для клонирования формы Jquery оказался весьма полезным. В нем есть все предустановленные, индексированные, вложенные формы, элементы управления и даже обратные вызовы, такие как beforeAdd, after add и т.д. Я упомянул об этом, потому что при поиске решения jQuery я оказался здесь. Поэтому я подумал, что это может помочь другим в поиске решения jQuery для клонирования форм