Jquery does not work after using Function . remove();

Asked

Viewed 154 times

0

Good morning,

I am making a form with tabs where the user can add and delete the tabs when needed, for the user to delete the tab use the function . remove() from jquery and the next tab is in place of the deleted one, my problem is that in the form I have a select that when I select it calls a function that loads some information only when I delete some tab select does not work and when I ask to debug it shows the message 'Undefined', can someone help me and find the error please? thank you.


$(function () {
  $(".cpf").mask("999999999-99");
  $(".tel").mask("(99) 9999-9999");
  $('#resp1').html('');                                   
  $('#cidadeID1').change(function() {   
    //alert('#cidadeID1');                 
    var optionID = $('#cidadeID1 option:selected').attr('class');
    if(optionID == 'educador'){
      $('#resp1').html(tabela2());
    }else{
      $('#resp1').html('');
    }
    //alert('fim #cidadeID1');
  });
  return false;
});

$(function () {

  $('#displayElem').html('1'); 
  $('#myTab a[href="#addTab"]').on('click', function () { 

    var nbrLiElem = ($('ul#myTab li').length) - 1; 
    if(nbrLiElem == 9){
      $("#last").hide();
    }
    var contador = nbrLiElem + 1;
    if(nbrLiElem > 9){
      var nbrLiElem = 1;

      return;
    }
    var ulttab = '#tab' + nbrLiElem;
    var ultli = '#li' + nbrLiElem;
    $('ul#myTab li:last-child').before('<li id="li' + (nbrLiElem + 1) + '"><a href="#tab' + (nbrLiElem + 1) + '" role="tab" data-toggle="tab"  class="atualizaraba' + (nbrLiElem + 1) + '"><span class="tit' + (nbrLiElem + 1) + '">' + (nbrLiElem + 1) + '</span> <span class="escondedel' + (nbrLiElem + 1) + '" onclick="removeTab(' + (nbrLiElem + 1) + ');" style="float: right;"><img src="img/nova/fechar.png" alt="Fechar" title="Fechar"></span></a>');

    var txt1 = '<div class="col-xs-6">';                                            
    var txt2 = '<h5 class="text-left modificah5" style="display:none">'+ (nbrLiElem + 1) +'</h5>';                   
    var txt3 = '<div class="form-group text-right alinhacampos4">';    
    var txt4 = '<label for="nome" class="text-right modificalabel1">Nome do Educador ou Gestor <span class="corobrigatorio">*</span></label>';
    var txt5 = '<input type="text" class="form-control modificainput1" name="nome_educador['+ (nbrLiElem + 1) +']">';                          
    var txt6 = '</div>';
    var txt7 = '<div class="form-group text-right alinhacampos4">';
    var txt8 = '<label for="cpf" class="text-right modificalabel1">CPF <span class="corobrigatorio">*</span></label>';    
    var txt9 = '<input type="text" class="form-control modificainput1 cpf" name="cpf['+ (nbrLiElem + 1) +']" id="cpf" class="required cpf" maxlength="14" autocomplete="off">';  
    var txt10 = '</div>';
    var txt11 = '<div class="form-group text-right alinhacampos4">';    
    var txt12 = '<label for="email" class="text-right modificalabel1">E-mail <span class="corobrigatorio">*</span></label>';
    var txt13 = '<input type="email" class="form-control modificainput1" name="email_educador['+ (nbrLiElem + 1) +']" id="email_educador">';     
    var txt14 = '</div>'; 
    var txt15 = '<div class="form-group text-right alinhacampos4">';
    var txt16 = '<label for="cidade" class="text-right campos1">Cargo <span class="corobrigatorio">*</span></label>';    
    var txt17 = '<select class="form-control campos2R required"  name="cidade['+ (nbrLiElem + 1) +']" id="cidadeID'+ (nbrLiElem + 1) +'">';
    var txt18 = '<option>Selecione</option>';    
    var txt19 = '<option class="diretor" value="diretor">Diretor</option>';
    var txt20 = '<option class="coordenador" value="coordenador">Coordenador</option>';    
    var txt21 = '<option class="educador" value="educador">Educador</option>';
    var txt22 = '<option class="equipe-tecnica" value="equipe-tecnica">Equipe Técnica</option>';    
    var txt23 = '<option class="educador-socioemocional" value="educador-socioemocional">Educador socioemocional</option>';
    var txt24 = '</select>';    
    var txt25 = '</div>';                                         
    var txt26 = '</div>';

    var txt27 = '<div class="col-xs-6" id="resp'+ (nbrLiElem + 1) +'">';                                                

    var txt28 = '</div>';  
    var somatxt =  txt1 + txt2 + txt3 + txt4 + txt5 + txt6 + txt7 + txt8 + txt9 + txt10 + txt11 + txt12 + txt13 + txt14 + txt15 + txt16 + txt17 + txt18 + txt19 + txt20 + txt21 + txt22 + txt23 + txt24 + txt25 + txt26 + txt27 + txt28;

    $(ulttab).after('<div class="tab-pane fade" id="tab' + (nbrLiElem + 1) + '">' + somatxt + '');
    nbrLiElem = nbrLiElem + 1;
    $('#displayElem').html(nbrLiElem);

    $('#cidadeID2').change(function() {
      //alert('#cidadeID2');
      var optionID2 = $('#cidadeID2 option:selected').attr('class');
      if(optionID2 == 'educador'){
        $('#resp2').html(tabela2());
      }else{
        $('#resp2').html('');
      }
      //alert('fim #cidadeID2');

    });
    $('#cidadeID3').change(function() {
      //alert('#cidadeID3');
      var optionID3 = $('#cidadeID3 option:selected').attr('class');
      if(optionID3 == 'educador'){
        $('#resp3').html(tabela2());
      }else{
        $('#resp3').html('');
      }
      //alert('fim #cidadeID3');
    });

    $('#cidadeID4').change(function() {
      //alert('#cidadeID4');
      var optionID4 = $('#cidadeID4 option:selected').attr('class');
      if(optionID4 == 'educador'){
        $('#resp4').html(tabela2());
      }else{
        $('#resp4').html('');
      }
      //alert('fim #cidadeID4');
    }); 
    $('#cidadeID5').change(function() {
      //alert('#cidadeID5');
      var optionID5 = $('#cidadeID5 option:selected').attr('class');
      if(optionID5 == 'educador'){
        $('#resp5').html(tabela2());
      }else{
        $('#resp5').html('');
      }
      //alert('fim #cidadeID5');
    }); 

    $('#cidadeID6').change(function() {
      //alert('#cidadeID6');
      var optionID6 = $('#cidadeID6 option:selected').attr('class');
      if(optionID6 == 'educador'){
        $('#resp6').html(tabela2());
      }else{
        $('#resp6').html('');
      }
      //alert('fim #cidadeID6');
    });
    $('#cidadeID7').change(function() {
      //alert('#cidadeID7');
      var optionID7 = $('#cidadeID7 option:selected').attr('class');
      if(optionID7 == 'educador'){
        $('#resp7').html(tabela2());
      }else{
        $('#resp7').html('');
      }
      //alert('fim #cidadeID7');
    });

    $('#cidadeID8').change(function() {
      //alert('#cidadeID8');
      var optionID8 = $('#cidadeID8 option:selected').attr('class');
      if(optionID8 == 'educador'){
        $('#resp8').html(tabela2());
      }else{
        $('#resp8').html('');
      }
      //alert('fim #cidadeID8');
    });
    $('#cidadeID9').change(function() {
      //alert('#cidadeID9');
      var optionID9 = $('#cidadeID9 option:selected').attr('class');
      if(optionID9 == 'educador'){
        $('#resp9').html(tabela2());
      }else{
        $('#resp9').html('');
      }
      //alert('fim #cidadeID9');
    });

    $('#cidadeID10').change(function() {
      //alert('#cidadeID10');
      var optionID10 = $('#cidadeID10 option:selected').attr('class');
      if(optionID10 == 'educador'){
        $('#resp10').html(tabela2());
      }else{
        $('#resp10').html('');
      }
      //alert('fim #cidadeID10');
    });   

    $(".cpf").mask("999999999-99");
    $("#li"+(nbrLiElem-1)).attr( "class", "" );
    $("#tab"+(nbrLiElem-1)).attr( "class", "tab-pane fade" );
    $("#li"+nbrLiElem).attr( "class", "active" );
    $("#tab"+nbrLiElem).attr( "class", "tab-pane fade in active" );

    return false;
  });
});

function removeTab(liElem) {
  if (confirm("Tem certeza que deseja excluir esta aba?")) {
    $('ul#myTab > li#li' + liElem).fadeOut(1000, function () {
      $(this).remove();
      $('#messagesAlert').text(''); 
    });

    $('div.tab-content div#tab' + liElem).remove();
    $('ul#myTab > li').not('#last').not('#li' + liElem).each(function(i){
      var getAttr = $(this).attr('id').split('li'); 
      $('ul#myTab li#li' + getAttr[1]).attr('id', 'li' + (i + 1));
      $('#myTab span[class="tit' + getAttr[1] + '"]').html((i + 1));
      $('#myTab span[class="tit' + getAttr[1] + '"]').attr('class', 'tit' + (i + 1));
      $('#myTab a[href="#tab' + getAttr[1] + '"]').attr('href', '#tab' + (i + 1));  

      $('#myTab a[class="atualizaraba' + getAttr[1] + '"]').attr('class', 'atualizaraba' + (i + 1));
      $('#myTab span[class="escondedel' + getAttr[1] + '"]').attr('class', 'escondedel' + (i + 1));
      $('#myTab span[onclick="removeTab(' + getAttr[1] + ');"]').attr('onclick', 'removeTab(' + (i + 1) +');');
      $('div.tab-content div#tab' + getAttr[1]).attr('id', 'tab' + (i + 1));

      $('div.tab-content input[name="nome_educador[' + getAttr[1] + ']"]').attr('name', 'nome_educador[' + (i + 1) +']');
      $('div.tab-content input[name="cpf[' + getAttr[1] + ']"]').attr('name', 'cpf[' + (i + 1) +']');
      $('div.tab-content input[name="email_educador[' + getAttr[1] + ']"]').attr('name', 'email_educador[' + (i + 1) +']');

      $('#cidadeID' + getAttr[1] + '').attr('name', 'cidade[' + (i + 1) +']');
      $('#cidadeID' + getAttr[1] + '').attr('id', 'cidadeID[' + (i + 1) +']');

      $('div.tab-content div[id="resp' + getAttr[1] + '"]').attr('id', 'resp' + (i + 1));
      $('#displayElem').html(i+1); 

      $('.escondedel' + (liElem-1) + '').show();
      if(i < 9){
        $("#last").show();
      }
      $("#li1").attr( "class", "active" );
      $("#tab1").attr( "class", "tab-pane fade in active" );  

    });
    return false;
  }
}
  • Post the code.

  • hi Laerte just posted, thank you.

  • @Thiago, I formatted your scripts, I found it strange you repeat the $('#cidadeIDN').change(function { ... } 10 times.

  • @Laert, I repeated the $('#cityIDN'). change(Function { ... } pq in the form can contain up to 10 tabs and each $('#cityIDN'). change(Function { ... } is responsible for controlling the select of each tab.

1 answer

0

Thiago, your problem is basically a side effect of bad practice... using selectors as variable.

for example, look at the following excerpt:

$('#cidadeID2').change(function() {
  //alert('#cidadeID2');
  var optionID2 = $('#cidadeID2 option:selected').attr('class');
  if(optionID2 == 'educador'){
    $('#resp2').html(tabela2());
  }else{
    $('#resp2').html('');
  }
  //alert('fim #cidadeID2');
});

He carries out the search for input#cidadeID2 and atrui an event change to the same. Where there is a change in the input#cidadeID2, he will make a search for div#resp2 and update your content.

But what happens when with the input#cidadeID2, when I exclude the tab1 that contain the input#cidadeID1? the input#cidadeID2 and div#resp2 are renamed to the input#cidadeID1 and div#resp1, but the previous event remains associated with input#cidadeID1, that will make the search for div#resp2... mess right?

The solution here is to create a scope for your Tab, I particularly like to use a Object and prototype, and a template for the tab.

Template (in HTML)

<template id="tmplLinha">
  <div class="tab-pane fade" id="tab{{indice}}">
    <div class="col-xs-6">
      <h5 class="text-left modificah5" style="display:none">{{indice}}</h5>
      <div class="form-group text-right alinhacampos4">
        <label for="nome" class="text-right modificalabel1">Nome do Educador ou Gestor <span class="corobrigatorio">*</span></label>
        <input type="text" class="form-control modificainput1" name="nome_educador[{{indice}}]">
      </div>
      <div class="form-group text-right alinhacampos4">
        <label for="cpf" class="text-right modificalabel1">CPF <span class="corobrigatorio">*</span></label>
        <input type="text" class="form-control modificainput1 cpf" name="cpf[{{indice}}]" id="cpf" class="required cpf" maxlength="14" autocomplete="off">
      </div>
      <div class="form-group text-right alinhacampos4">
        <label for="email" class="text-right modificalabel1">E-mail <span class="corobrigatorio">*</span></label>
        <input type="email" class="form-control modificainput1" name="email_educador[{{indice}}]" id="email_educador">
      </div>
      <div class="form-group text-right alinhacampos4">
        <label for="cidade" class="text-right campos1">Cargo <span class="corobrigatorio">*</span></label>
        <select class="form-control campos2R required"  name="cidade[{{indice}}]" id="cidadeID{{indice}}">
          <option>Selecione</option>
          <option class="diretor" value="diretor">Diretor</option>
          <option class="coordenador" value="coordenador">Coordenador</option>
          <option class="educador" value="educador">Educador</option>
          <option class="equipe-tecnica" value="equipe-tecnica">Equipe Técnica</option>
          <option class="educador-socioemocional" value="educador-socioemocional">Educador socioemocional</option>
        </select>
      </div>                                         
    </div>
    <div class="col-xs-6" id="resp{{indice}}">
    </div>
  </div>
</template>
<template id="tmplTitulo">
  <li id="li{{indice}}">
    <a href="#tab{{indice}}" role="tab" data-toggle="tab"  class="atualizaraba{{indice}}">
      <span class="tit{{indice}}">{{indice}}</span> 
      <span class="escondedel{{indice}}" onclick="removeTab({{indice}});" style="float: right;">
        <img src="img/nova/fechar.png" alt="Fechar" title="Fechar">
      </span>
    </a>
  </li>
</template>

Script Tab

var quantidade = 1;
var tabs = [];
var Tab = function () {
  var self = this;
  this.indice = quantidade;
  this.titulo = {};
  this.conteudo = {};
  this.titulo.container = $("#li" + indice); 
  this.conteudo.container = $("#tab" + indice);     

  // caso não encontre uma tab com o indice especificado
  if (!this.titulo.container || this.titulo.container.length == 0) {        
    var anterior = this.indice - 1;
    this.titulo.anterior = $("#li" + anterior);
    this.conteudo.anterior = $("#tab" + anterior);

    this.titulo.container = $(this.tmplTitulo.replace("{{indice}}", indice));
    this.conteudo.container = $(this.tmplLinha.replace("{{indice}}", indice));

    this.titulo.anterior.after(this.titulo.container);
    this.conteudo.anterior.after(this.conteudo.container);
  }

  this.titulo.atualizaraba = $(".atualizaraba" + this.indice, this.titulo.container);
  this.titulo.tit = $(".tit" + this.indice, this.titulo.container);
  this.titulo.escondedel = $(".escondedel" + this.indice, this.titulo.container);

  this.conteudo.modificah5 = $(".modificah5", this.conteudo.container);
  this.conteudo.nome_educador = $("input[name='nome_educador[" + this.indice + "]']", this.conteudo.container);
  this.conteudo.cpf = $("input[name='cpf[" + this.indice + "]']", this.conteudo.container);
  this.conteudo.email_educador = $("input[name='email_educador[" + this.indice + "]']", this.conteudo.container);
  this.conteudo.cidade = $("input[name='cidade[" + this.indice + "]']", this.conteudo.container);
  this.conteudo.resp = $("resp" + this.indice, this.conteudo.container);

  this.titulo.escondedel.click(function () {
    self.onEscondedelClick();
  });

  this.conteudo.cpf.mask("999999999-99");
  this.conteudo.resp.html('');                                   
  this.conteudo.cidade.change(function() {   
    self.onCidadeClick();
  });
  quantidade++;
}

Tab.prototype.quantidade = 1;
Tab.prototype.tmplLinha = document.getElementById("tmplLinha").innerHTML;
Tab.prototype.tmplTitulo = document.getElementById("tmplTitulo").innerHTML;
Tab.prototype.atualizarIndice = function (indice) {
  this.indice = indice;
  this.titulo.container.attr("id", "li" + this.indice);
  this.titulo.tab.attr("href", "#tab" + this.indice);
  this.titulo.tab.attr("class", "atualizaraba" + this.indice);
  this.titulo.tit.attr("class", "tit" + this.indice);
  this.titulo.tit.text(this.indice);
  this.titulo.escondedel.attr("class", "escondedel" + this.indice);
  this.titulo.escondedel.attr("class", "escondedel" + this.indice);

  this.titulo.container.attr("id", "tab" + this.indice);
  this.conteudo.modificah5.attr("class", "modificah5" + this.indice);
  this.conteudo.nome_educador.attr("name", "nome_educador[" + this.indice + "]");
  this.conteudo.cpf.attr("name", "cpf[" + this.indice + "]");
  this.conteudo.email_educador.attr("name", "email_educador[" + this.indice + "]");
  this.conteudo.cidade.attr("name", "cidade[" + this.indice + "]");
  this.conteudo.cidade.attr("id", "cidadeID" + this.indice);
  this.conteudo.resp.attr("id", "resp" + this.indice);
}

Tab.prototype.onEscondedelClick = function () {
  if (confirm("Tem certeza que deseja excluir esta aba?")) {
    tabs.splice(this.indice - 1, 1);
    this.titulo.container.remove();
    this.conteudo.container.remove();
    for (var index = this.indice - 1; this.indice < tabs.length; index++) {
      tabs[index].atualizarIndice(tabs[index].indice - 1);
    }
    quantidade--;
  }
}

Tab.prototype.onCidadeClick = function () {
  var optionID = this.conteudo.cidade.attr('class');
  if(optionID == 'educador'){
    this.conteudo.resp.html(tabela2());
  }else{
    this.conteudo.resp.html('');
  }
}

var addTab = $('#myTab a[href="#addTab"]');
addTab.on('click', function () { 
  tabs.push(new Tab());
});
addTab.trigger("click"); //criar o objeto Tab para a tab1;

Updating

The above code uses javascript only and we have a clear grouping of tab elements, but since you are not used to Javascript, then try replacing the following code block:

$('#cidadeID2').change(function() {
  //alert('#cidadeID2');
  var optionID2 = $('#cidadeID2 option:selected').attr('class');
  if(optionID2 == 'educador'){
    $('#resp2').html(tabela2());
  }else{
    $('#resp2').html('');
  }
  //alert('fim #cidadeID2');

});
$('#cidadeID3').change(function() {
  //alert('#cidadeID3');
  var optionID3 = $('#cidadeID3 option:selected').attr('class');
  if(optionID3 == 'educador'){
    $('#resp3').html(tabela2());
  }else{
    $('#resp3').html('');
  }
  //alert('fim #cidadeID3');
});

$('#cidadeID4').change(function() {
  //alert('#cidadeID4');
  var optionID4 = $('#cidadeID4 option:selected').attr('class');
  if(optionID4 == 'educador'){
    $('#resp4').html(tabela2());
  }else{
    $('#resp4').html('');
  }
  //alert('fim #cidadeID4');
}); 
$('#cidadeID5').change(function() {
  //alert('#cidadeID5');
  var optionID5 = $('#cidadeID5 option:selected').attr('class');
  if(optionID5 == 'educador'){
    $('#resp5').html(tabela2());
  }else{
    $('#resp5').html('');
  }
  //alert('fim #cidadeID5');
}); 

$('#cidadeID6').change(function() {
  //alert('#cidadeID6');
  var optionID6 = $('#cidadeID6 option:selected').attr('class');
  if(optionID6 == 'educador'){
    $('#resp6').html(tabela2());
  }else{
    $('#resp6').html('');
  }
  //alert('fim #cidadeID6');
});
$('#cidadeID7').change(function() {
  //alert('#cidadeID7');
  var optionID7 = $('#cidadeID7 option:selected').attr('class');
  if(optionID7 == 'educador'){
    $('#resp7').html(tabela2());
  }else{
    $('#resp7').html('');
  }
  //alert('fim #cidadeID7');
});

$('#cidadeID8').change(function() {
  //alert('#cidadeID8');
  var optionID8 = $('#cidadeID8 option:selected').attr('class');
  if(optionID8 == 'educador'){
    $('#resp8').html(tabela2());
  }else{
    $('#resp8').html('');
  }
  //alert('fim #cidadeID8');
});
$('#cidadeID9').change(function() {
  //alert('#cidadeID9');
  var optionID9 = $('#cidadeID9 option:selected').attr('class');
  if(optionID9 == 'educador'){
    $('#resp9').html(tabela2());
  }else{
    $('#resp9').html('');
  }
  //alert('fim #cidadeID9');
});

$('#cidadeID10').change(function() {
  //alert('#cidadeID10');
  var optionID10 = $('#cidadeID10 option:selected').attr('class');
  if(optionID10 == 'educador'){
    $('#resp10').html(tabela2());
  }else{
    $('#resp10').html('');
  }
  //alert('fim #cidadeID10');
});  

by the following:

var cidade = $('#cidadeID' + nbrLiElem);
var resp = $('#resp' + nbrLiElem);

cidade.change(function() {
  //alert('#cidadeID10');
  var optionID = cidade.find('option:selected').attr('class');
  if(optionID == 'educador'){
    resp.html(tabela2());
  }else{
    resp.html('');
  }
}); 

note that I am conducting the search for select#cidadeIDN and div#respN only once, then just use it.

In any case, I accompany you to read the following materials:

  • hi @Tobymosque, regarding the mess you described in the code could you give me a suggestion to resolve and let the code work please? as I do not know the prototype you could help me using Jquey, thank you very much for the help.

  • @Thiagophilipp, I made some changes, also put a reading suggestion for you.

Browser other questions tagged

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