Цикл над массивом и создание тегов ввода формы после меток

Я пытаюсь перебрать массив для создания некоторых тегов формы, в зависимости от того, сколько значений в массиве. Пока у меня есть свой ярлык и входные теги, которые создаются. Проблема, с которой я столкнулся, заключается в правильном отображении входных тегов после меток. Любая помощь приветствуется!

Я пытаюсь добиться:

<label class="material-label" for="leather_materials">
<input id="leather_materials" class="shoe-materials" type="radio" name="materials" value="leather">
<label class="material-label" for="suade_materials">
<input id="suade_materials" class="shoe-materials" type="radio" name="materials" value="suade">
<label class="material-label" for="nubuck_materials">
<input id="nubuck_materials" class="shoe-materials" type="radio" name="materials" value="nubuck">

мой код до сих пор:

materialArray = ['leather','suade','nubuck'];

//loop over material array 
for( i = 0; i < materialArray.length;  i++) {

    //create label elements
    var matLabel = document.createElement('label');
    matLabel.setAttribute('for', materialArray[i] + '_materials');
    matLabel.setAttribute('class', 'material-label');
    console.log(matLabel);

    //add text to label elements
    var matLabelTextNode = document.createTextNode(materialArray[i]);
    matLabel.appendChild(matLabelTextNode);

    //create input elements
    var matInput = document.createElement('input');
    matInput.className = 'shoe-materials';
    matInput.setAttribute('class', 'shoe-materials');
    matInput.setAttribute('id', materialArray[i] +'_materials');
    matInput.setAttribute('name', 'materials');
    matInput.setAttribute('type', 'radio');
    matInput.setAttribute('value', materialArray[i]);
    console.log(matInput);   

    //append to parent div
    addMaterials.appendChild(matLabel);    
    $('.material-label').after(matInput);        
}

Я попытался использовать jQuery after(), но он немного испортился и получил следующее

<label class="material-label" for="leather_materials">leather</label>
<input id="nubuck_materials" class="shoe-materials" type="radio" name="materials" value="nubuck">
<input id="suade_materials" class="shoe-materials" type="radio" name="materials" value="suade">
<input id="leather_materials" class="shoe-materials" type="radio" name="materials" value="leather">
<label class="material-label" for="suade_materials">suade</label>
<input id="nubuck_materials" class="shoe-materials" type="radio" name="materials" value="nubuck">
<input id="suade_materials" class="shoe-materials" type="radio" name="materials" value="suade">
<label class="material-label" for="nubuck_materials">nubuck</label>
<input id="nubuck_materials" class="shoe-materials" type="radio" name="materials" value="nubuck">

4 ответа

Решение

Замените ".material-label" на matLabel

$(matLabel).after(matInput);  

Вот JSFiddle: https://jsfiddle.net/82o6hfna/

Оператор JQuery $('.material-label') выбирает каждый элемент с этим классом, поэтому, когда вы используете $('.material-label').after(matInput)Вы добавляете содержимое matInput после каждой из трех меток.

Чтобы получить текущую метку, просто используйте i в качестве индекса для массива, возвращаемого $('.material-label'),

изменения

//append to parent div
addMaterials.appendChild(matLabel);
$('.material-label').after(matInput);

к

//append to parent div
currentLabel = $('.material-label')[i];
$(currentLabel).after(matInput);    

Получите результаты, которые вы хотите.

Ошибка, которую вы делаете, это добавление этих элементов после .material-label элемент. Таким образом, вы продолжаете добавлять их после ярлыков, которые уже имеют этот класс.

От:

$('.material-label').after(matInput);

Для того, чтобы:

$(matLabel).after(matInput);

Обновленный код:

var addMaterials = document.getElementById("addMaterials");
materialArray = ['leather','suade','nubuck'];

//loop over material array 
for( i = 0; i < materialArray.length;  i++) {

    //create label elements
    var matLabel = document.createElement('label');
    matLabel.setAttribute('for', materialArray[i] + '_materials');
    matLabel.setAttribute('class', 'material-label');
    console.log(matLabel);

    //add text to label elements
    var matLabelTextNode = document.createTextNode(materialArray[i]);
    matLabel.appendChild(matLabelTextNode);

    //create input elements
    var matInput = document.createElement('input');
    matInput.className = 'shoe-materials';
    matInput.setAttribute('class', 'shoe-materials');
    matInput.setAttribute('id', materialArray[i] +'_materials');
    matInput.setAttribute('name', 'materials');
    matInput.setAttribute('type', 'radio');
    matInput.setAttribute('value', materialArray[i]);
    console.log(matInput);   

    //append to parent div
    addMaterials.appendChild(matLabel);    
    $(matLabel).after(matInput);        
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<div id="addMaterials"></div>

Мне никогда не нравился подход манипулирования объектами к созданию HTML. Мне нравится строить строки HTML, а затем вставить его в DOM. Просто мое мнение.

JS

//to uppercase of first letter only
String.prototype.toUpperCaseFirstLetter = function() {
    var s = this;
    return s.length > 0 ? s.charAt(0).toUpperCase() + s.slice(1) : s;
}

var materialArray = ['leather','suade','nubuck'];

function buildMaterialRadios () {
    var str = '';
    for (var i = 0; i < materialArray.length; i++) {
      var item = materialArray[i];
      str += '<label class="material-label" for="'+item+'_materials">'+item.toUpperCaseFirstLetter()+'</label><input id="'+item+'_materials" class="shoe-materials" type="radio" name="materials" value="'+item+'">';
    };

    document.getElementById('material_selections').innerHTML = str;
}


buildMaterialRadios();

HTML

<form name="shoebuilderform">

<div id="material_selections"></div>

</form>

http://jsfiddle.net/qcmdnd4d/

Другие вопросы по тегам