What to do when looping repeats in 2 different areas

Asked

Viewed 153 times

0

The code takes the values of inputs and sends it to the textarea but when added more than one titulo the values are repeated in the result of the titles, for example, the descriptions of the title 1 is the same as the title 2 vice and versa, why does this happen? and how to make it work without changing the purpose?

Execute the code on codepen.io or jsfiddle.net

What happens:
ERRADO
What should happen:
CERTO

function resultado() {
  var inp2 = document.getElementsByName("inp2");
  var titu = document.getElementsByName("titu");
  var res = document.getElementById("resultado");
  res.value = "";
  
if (titu[0]) {
  for (var k = 0; k < titu.length; k++) {
    if (titu[k].value.trim() != '') {
      res.value += `<div>
<span>${titu[k].value.trim()}</span>
</div>
<ul>\n`;
      for (var j = 0; j < inp2.length; j++) {
        if (inp2[j].value.trim() != '') {
          res.value += `<li>${inp2[j].value.trim()}</li>\n`;
        }
      }
    }
  }
}else {
  console.log("error")
  res.value += `<ul>\n`;
    for (var l = 0; l < inp2.length; l++) {
      if (inp2[l].value.trim() != '') {
        res.value += `<li>${inp2[l].value.trim()}</li>\n`;
      }
    }
 }
};

// -----------------------------------------

let cont2 = 1;
document.getElementById("add2").onclick = function clone2() {
  let container2 = document.getElementById("saida2");  
  let tempLinha2 = document.querySelector('#template2'); 
  let clonar2 = document.importNode(tempLinha2.content, true); 
  
  const label2 = clonar2.querySelector("label");
  label2.htmlFor = cont2;
  clonar2.querySelector("input").className = cont2;
  
  container2.appendChild(clonar2);
  cont2++;
};
document.getElementById("del2").onclick = function del2() {
    document.querySelector('#saida2 #linha2:last-child').remove();
};

// ---------------------------------------

let cont3 = 1;
document.getElementById("addtit").onclick = function clone3() {
  let container3 = document.getElementById("saida2");  
  let tempLinha3 = document.querySelector('#template3');
  let clonar3 = document.importNode(tempLinha3.content, true); 
  
  const label3 = clonar3.querySelector("label");
  label3.htmlFor = cont3;
  clonar3.querySelector("input").className = cont3;
  
  container3.appendChild(clonar3);
  cont3++;
  document.getElementById('add2').id = 'add3';
  document.getElementById('del2').id = 'del3';
};
document.getElementById("deltit").onclick = function deltit() {
    document.querySelector('#saida2 #alg:last-child').remove();
    document.getElementById('add3').id = 'add2';
    document.getElementById('del3').id = 'del2';
};

// -----------------------------------------
if (document.getElementById("add3")) {
let cont4 = 1;
document.getElementById("add3").onclick = function clone4() {
  let container4 = document.getElementById("saida3");  
  let tempLinha4 = document.querySelector('#template2');
  let clonar4 = document.importNode(tempLinha4.content, true); 
  
  const label4 = clonar4.querySelector("label");
  label4.htmlFor = cont4;
  clonar4.querySelector("input").className = cont4;
  
  container4.appendChild(clonar4);
  cont4++;
};
document.getElementById("del3").onclick = function del4() {
  document.querySelector('#saida3 #linha2:last-child').remove();
};
}
<div class="container">
<button id="addtit">+ TITULO</button>
<button id="deltit">- TITULO</button>
<button id="add2">+ DESCRIÇÃO</button>
<button id="del2">- DESCRIÇÃO</button>
<div id="saida2"></div>
<div class='botoes'>
<button onclick="resultado()" id='concluir'>CONCLUIR</button>
</div>
<div class="header"><span class="titulo">RESULTADO</span>
</div>
<div class="linha"><textarea id="resultado"></textarea>
</div>
</div>
  

<!-- template 2 -->
<template id="template2">
<div class="linha" id="linha2"><div class="coluna1"><label for="0">DESCRIÇÃO:</label></div><div class="coluna2"><input name="inp2" class="0" type="text"/></div>
</div>
</template>
<!-- template 3 -->
<template id="template3">
<div id="alg">
<div class="linha"><div class="coluna1"><label for="0">TITULO:</label></div><div class="coluna2"><input name="titu" class="0" type="text"/></div>
</div>
<div class="linha" id="linha3"><div class="coluna1"><label for="0">DESCRIÇÃO:</label></div><div class="coluna2"><input name="inp2" class="0" type="text"/></div>
</div>
<div id="saida3"></div>
</div>
</template>

  • By the tests, the inputs are always with the same name, in fact, each input should have a different id, so you can take the values of each

  • Yes, but like every other id should be unique, how to pass from name for id and maintain the loop

2 answers

1


You need to organize your inputs, follow an example

var titulos = []
var divTitulos = document.getElementById("titulos")
var tmplTitulo = document.getElementById("tmplTitulo").content
var tmplDescricao = document.getElementById("tmplDescricao").content

var btAddTitulo = document.getElementById("addTitulo")
var btDelTitulo = document.getElementById("delTitulo")
var btAddDescricao = document.getElementById("addDescricao")
var btDelDescricao = document.getElementById("delDescricao")
var btConcluir = document.getElementById("concluir")
var txtSaida = document.getElementById("saida")

var addTitulo = function () {
  var wrapper = document.importNode(tmplTitulo, true)
  divTitulos.appendChild(wrapper)
  wrapper = divTitulos.children[divTitulos.children.length - 1]
  
  var titulo = {
    wrapper: wrapper,
    input: wrapper.querySelector('.titulo'),
    delTitulo: wrapper.querySelector('.delTitulo'),
    addDescricao: wrapper.querySelector('.addDescricao'),
    divDescricoes: wrapper.querySelector('.descricoes'),
    descricoes: []
  }
  
  titulo.delTitulo.addEventListener('click', delTitulo.bind(titulo))
  titulo.addDescricao.addEventListener('click', addDescricao.bind(titulo))  
  titulos.push(titulo)
}

var delTitulo = function () {
  this.wrapper.remove()
  var index = titulos.indexOf(this)
  titulos.splice(index, 1);
}

var addDescricao = function () {
  var wrapper = document.importNode(tmplDescricao, true)
  this.divDescricoes.appendChild(wrapper)
  wrapper = this.divDescricoes.children[this.divDescricoes.children.length - 1]
  
  var descricao = {
    titulo: this,
    wrapper: wrapper,
    input: wrapper.querySelector('.descricao'),
    delDescricao: wrapper.querySelector('.delDescricao')
  }
  
  descricao.delDescricao.addEventListener('click', delDescricao.bind(descricao))  
  this.descricoes.push(descricao)
}

var delDescricao = function () {
  this.wrapper.remove()
  var index = this.titulo.descricoes.indexOf(this)
  this.titulo.descricoes.splice(index, 1);
}

var concluir = function () {
  var html = '<div>';
  titulos.forEach(function (titulo) {
    html += `
  <div>
    <span>${titulo.input.value}</span>
  </div>
  <ul>`;
    titulo.descricoes.forEach(function (descricao) {
      html += `    
    <li>${descricao.input.value}</li>`
    })
  html += `
  </ul>
`
  })
  html += `</div>`
  txtSaida.value = html
}

btAddTitulo.addEventListener("click", addTitulo)
btConcluir.addEventListener("click", concluir)
.acoes {
  margin-bottom: 5px;
}

.descricoes > div {
  margin-top: 5px;
}

#saida {
  margin-top: 5px;
  width: 500px;
  height: 200px;
}
<template id="tmplTitulo">
  <fieldset>
    <legend>Conteudo</legend>
    <div class="acoes">
      <input class="delTitulo" type="button" value="Remover Titulo" />
      <input class="addDescricao" type="button" value="Adicionar Descrição" />
    </div>
    <div>
      <label>
        Titulo
        <input type="text" class="titulo" />
      </label>  
    </div>
    <div class="descricoes">
    </div>
  </fieldset>
</template>

<template id="tmplDescricao">
  <div>
    <label>
      Descrição
      <input type="text" class="descricao" />
    </label>  
    <input class="delDescricao" type="button" value="Remover Descrição" />
  </div>
</template>

<div>
  <div id="acoes">
    <input id="addTitulo" type="button" value="Adicionar Titulo" />
    <input id="concluir" type="button" value="Concluir" />
  </div>
  <div id="titulos">
  </div>
  <div>
    <textarea id="saida" readonly></textarea>
  </div>
</div>

  • I gave the reward for the wrong answer and now what I do?

0

The problem is in that part of the code:

if (titu[0]) {
  for (var k = 0; k < titu.length; k++) {
    if (titu[k].value.trim() != '') {
      res.value += `<div>
<span>${titu[k].value.trim()}</span>
</div>
<ul>\n`;
      for (var j = 0; j < inp2.length; j++) {
        if (inp2[j].value.trim() != '') {
          res.value += `<li>${inp2[j].value.trim()}</li>\n`;
        }
      }
    }
  }
}

Titles and descriptions have the same name titu and inp2 and you’re creating a looping for each one and it ends up resulting in what’s in the first image. You can change your code and put different names and ids.
But if you don’t want to change your code, you should use a loop for both, like this code here:

if (titu[0]) {
  for (var k = 0; k < titu.length; k++) {
    if (titu[k].value.trim() != '') {
      res.value += `<div>
<span>${titu[k].value.trim()}</span>
</div>
<ul>\n`;
        if (inp2[k].value.trim() != '') {
         res.value += `<li>${inp2[k].value.trim()}</li>\n`;
      }
    }
  }
}
  • It only works if it is with a description, if adding more of one the others do not work.

Browser other questions tagged

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