Creating html elements in looping javascript

0

I'm pretty new with javascript and when it comes to creating loopings I totally lose myself, the code below is to create the elements with each click and number the id and the text, but I'm having difficulties with that, I I managed to solve with an input and adding the quantity, but this is not the result that I need, how should I proceed? If possible explain the changes, Thanks.

document.getElementById("add1").onclick = function clone(){
	var qt = 1;
	var container = document.getElementById("saida1");
	while (container.hasChildNodes()) {
		container.removeChild(container.lastChild);
	}
	for (i=0;i<qt;i++){

		var input = document.createElement("input");
		var div1 = document.createElement("div");
		var div2 = document.createElement("div");
		var div3 = document.createElement("div");
		var label = document.createElement("label");
		div1.className = "linha";
		div2.className = "coluna1";
		div3.className = "coluna2";
		label.htmlFor = (i+1)
		label.textContent = "Texto " + (i+1) + ": ";
		input.className = (i+1);
		input.name = "inp";
		input.type = "text";
		container.appendChild(div1);
		div1.appendChild(div2);
		div2.appendChild(label);
		div1.appendChild(div3);
		div3.appendChild(input);
	}
}
<div id="saida1"></div>
<button id="add1">ADD</button>
    
asked by anonymous 06.08.2018 / 18:24

3 answers

2

There are improvements that can be made to your code, but to answer your questions about loop and how to do the counter, I'll keep the code as is and add comments to explain:

document.getElementById("add1").onclick = function clone() {
    // removi o qt que não será mais usado e estava sem função como explicarei abaixo
    var container = document.getElementById("saida1");
    // removi o while, que só estava excluindo os elementos, por isso também aparecia somente um
    
    // conta quantos elementos com classe linha existem
    // isso vai servir para montar o label e o id dos novos elementos
    var i = document.querySelectorAll(".linha").length;

   // removi o for porque, como qt sempre era igual a 1, nunca contava nada diferente e só executava uma vez
    var input = document.createElement("input");
    var div1 = document.createElement("div");
    var div2 = document.createElement("div");
    var div3 = document.createElement("div");
    var label = document.createElement("label");
    div1.className = "linha";
    div2.className = "coluna1";
    div3.className = "coluna2";
    label.htmlFor = (i + 1)
    label.textContent = "Texto " + (i + 1) + ": ";
    input.className = (i + 1);
    input.name = "inp";
    input.type = "text";
    container.appendChild(div1);
    div1.appendChild(div2);
    div2.appendChild(label);
    div1.appendChild(div3);
    div3.appendChild(input);
}
<div id="saida1"></div>
<button id="add1">ADD</button>
    
06.08.2018 / 18:47
3

Each click on the "ADD" button you want to add a new input, right?

Why do you remove all fields before adding +1?

while (container.hasChildNodes()) {

    container.removeChild(container.lastChild);

}

To solve the problem, you need to:

  • Count how many elements are already inserted in the "out" container.
  • Store the quantity in any variable added by +1.
  • Insert new input
  • You do not need a loop, you can do:

    document.getElementById("add1").onclick = function clone() {
    
        //Local onde será inserido o input
    	var container = document.getElementById("saida1");
    
        //Conta total de elementos e soma +1 para o que irá ser adicionado
        var total = container.childElementCount+1
    
        var input = document.createElement("input");
    	var div1 = document.createElement("div");
    	var div2 = document.createElement("div");
    	var div3 = document.createElement("div");
    	var label = document.createElement("label");
    
    	div1.className = "linha";
    	div2.className = "coluna1";
    	div3.className = "coluna2";
    
        //diferencie os labels para que sejam unicos
    	label.htmlFor = 'input_' + total
        //insira o titulo com o novo total
    	label.textContent = "Texto " + total + ": ";
    	input.className = total;
    	input.name = "inp";
    	input.type = "text";
        //Inclui um ID para cada input, de acordo com o label
        input.id = 'input_' + total;
    	container.appendChild(div1);
    	div1.appendChild(div2);
    	div2.appendChild(label);
    	div1.appendChild(div3);
    	div3.appendChild(input);
    }
    <div id="saida1"></div>
    <button id="add1">ADD</button>
        
    06.08.2018 / 18:47
    1

    The other answers you have already explained the problem and what you did wrong, but I want to show another solution to the same problem.

    If you need to add a lot of html dynamically you can use templates

    Example:

    let cont = 1;
    document.getElementById("add1").onclick = function clone() {
      let container = document.getElementById("saida1");  
      let tempLinha = document.querySelector('#templateLinha'); //obter o template
      let clone = document.importNode(tempLinha.content, true); //clonar
      
      //alterar o que interessa no template clonado
      const label = clone.querySelector("label");
      label.htmlFor = cont;
      label.textContent = "Texto " + (cont) + ": ";
      clone.querySelector("input").className = cont;
      
      container.appendChild(clone);
      cont++;
    }
    <div id="saida1"></div>
    <button id="add1">ADD</button>
    
    <!-- aqui está o template do html que cada nova linha leva -->
    <template id="templateLinha">
      <div class="linha">
        <div class="coluna1">
            <label for="1">Texto 1: </label>
        </div>
        <div class="coluna2">
          <input class="1" name="inp" type="text">
        </div>
      </div>
    </template>

    Notice that in html I have added a new tag <template> with the structure you add in each line. This also has the advantage of clarifying the html that constitutes each one. Then about the clone that was created, I got the elements I wanted with querySelector and I just changed the things that needed to be different.

    I hereby leave the warning that this functionality is not supported in the old Internet Explorer.

        
    06.08.2018 / 22:13