Клонирование и переименование элементов формы с jQuery

Я ищу эффективный способ или клонироваться/переименовать или воссоздать поля адреса для предложения способности отправить несколько адресов на той же странице. Таким образом с примером формы как это:

<div id="addresses">
  <div class="address">
    <input type="text" name="address[0].street">
    <input type="text" name="address[0].city">
    <input type="text" name="address[0].zip">
    <input type="text" name="address[0].state">
  </div>
</div>
<a href="" id="add_address">Add address form</a>

Из того, что я могу понять, что существует две опции сделать это:

  1. Воссоздайте поле формы полем и увеличьте индекс, который является довольно подробным:

    var index = $(".address").length;
    
    $('<`input`>').attr({
    name: 'address[' + index + '].street',
    type: 'text'
    }).appendTo(...);
    
    $('<`input`>').attr({
    name: 'address[' + index + '].city',
    type: 'text'
    }).appendTo(...);
    
    $('<`input`>').attr({
    name: 'address[' + index + '].zip',
    type: 'text'
    }).appendTo(...);
    
    $('<`input`>').attr({
    name: 'address[' + index + '].state',
    type: 'text'
    }).appendTo(...);
    
  2. Клонируйте Существующий слой и замените имя в клоне:

    $("div.address").clone().appendTo($("#addresses"));
    

Какой делают Вы рекомендуете использовать с точки зрения того, чтобы быть более эффективным и если бы его № 2 может Вы предлагать, как я пошел бы о поиске и заменяющий все случаи [0] с [1] ([n]).Спасибо.

17
задан SLaks 16 April 2010 в 00:21
поделиться

2 ответа

Теоретически самым простым способом было бы клонировать, а затем изменить имя:

var newaddress= $("#addresses div.address").eq(0).clone();
newaddress.find('input').each(function() {
    this.name= this.name.replace('[0]', '['+i+']');
});
$('#addresses').append(newaddress);

Однако:

a. jQuery clone () - действительно неприятная работа. В IE он сериализует узлы в HTML, обрабатывает строку HTML с помощью регулярного выражения (!), Чтобы удалить атрибуты внутреннего идентификатора bodge-job, а затем просит браузер повторно проанализировать его. Это одна из моих наименее любимых частей jQuery: она очень подвержена ошибкам, теряет некоторую информацию и работает медленно (не то чтобы скорость имела значение для той небольшой работы, которую вы здесь выполняете).

Собственный в браузере метод cloneNode (true) намного лучше, но вы не можете его использовать, если вы работаете с jQuery, потому что он будет копировать внутренние идентификаторы jQuery, что может сбить с толку его сценарии. Фу. Какой беспорядок.

б. Когда вы меняете имя входа, будь то с помощью input.name , как здесь, или с помощью attr () , как в вашем примере, в IE <= 7 возникают проблемы.

В частности, хотя входные данные будут отправлены с правильным именем элемента управления, они не будут проиндексированы под правильным именем в form.elements HTMLCollection (или в форме сам, хотя вам все равно не стоит его использовать). Это не обязательно проблема, если вы выбираете входные данные на основе идентификаторов или селекторов jQuery, а не интерфейса HTMLCollection старой школы. Хуже того, переключатели, если вы их используете, не будут правильно сгруппированы по именам.

Если вас это беспокоит, я боюсь, что использование innerHTML / html () для создания div, как в ответе pst, - ваш единственный вариант.(Вы всегда можете объединить два, создавая с помощью HTML, а затем изменяя другие атрибуты и текстовое содержимое, используя text () , attr () , val () и т. Д. ... чтобы избежать обычных проблем с экранированием HTML, когда вы вставляете текстовые строки в HTML.)

32
ответ дан 30 November 2019 в 11:52
поделиться

Это будет гораздо менее многословно, если вы напишете его разумно :-) Я бы, вероятно, просто использовал clone и append. Однако вы получите повторяющиеся имена. Это не имеет большого значения, если ваша внутренняя часть может правильно обрабатывать «адрес []. Улица», но может и нет, и в таком случае вам нужно будет выполнить очистку после клона. Поэтому я бы рекомендовал «спрятать это в аккуратной функции построителя».

function createAddress (index) {
  return jQuery(replace('\
    <div class="address">\
      <input type="text" name="address[{i}].street">\
      <input type="text" name="address[{i}].city">\
      <input type="text" name="address[{i}].zip">\
      <input type="text" name="address[{i}].state">\
    </div>\
    ', {i: index}))
}

Где replace - это некоторая аккуратная функция, которая понимает простое отображение интерполяции. Я предпочитаю «хранить разметку во чем-то похожем на разметку».

Беспокойство о производительности здесь, вероятно, не оправдано.

4
ответ дан 30 November 2019 в 11:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: