Creating html elements in javascript looping

Asked

Viewed 1,365 times

0

I am very new with javascript and when it comes to creating loopings I get totally lost, the code below is to create the elements with each click and number the id and the text, but I’m having difficulties about it, I managed to, solve with an input and adding the amount, but that’s not the result I need, how should I proceed? If possible explain the amendments, Thank you.

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>

  • 1

    first, if the variable "Qt" is always 1, this command for (i=0;i<qt;i++){ is purposeless, will always do everything once, it is unnecessary. Second, this line removes the items you already have in the div "container": container.removeChild(container.lastChild); then only 1 element will appear always. Finally, you would have to count how many elements you have in the div "container" in order to be able to number

  • i forgot to remove ...container.removeChild(container.lastChild);... when I made the code using input to get the values

3 answers

3

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

Pq you remove all fields before adding +1?

while (container.hasChildNodes()) {

    container.removeChild(container.lastChild);

}

To solve the problem, you need:

  1. Count how many elements are already inserted in the container "out1".
  2. Store the quantity in some added variable of +1.
  3. Insert the new input

You don’t need a loop, 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>

  • i forgot to remove ...container.removeChild(container.lastChild);... when I made the code using input to get the values

2


There are improvements that can be made to your code, but to answer your questions about the loop and how to do the counter, I will 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>

1

The other answers you have already explain 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 that make the process easier for you, as it allows you to keep the html you want to create as html and create the new elements by cloning what is already in html.

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>

Note that in html I added a new tag <template> with the structure you add on each line. This also has the advantage of making the html that makes up each one clearer. Then about the clone which was created, I obtained the elements I intended with querySelector and traded only the things that needed to be different.

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

  • Very interesting did not know, I will test thank you.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.