Maintain select element value when cloning with jQuery and deleting Labels

Asked

Viewed 110 times

5

Test scenario

function addReg(){

	var reg = $('#registro').clone().removeAttr('id');
	reg.children('label').remove();
	$('#formX').append(reg);
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="container">
	
	<div class="row">
		<form id="formX" method="get" action="kk.php">
			<div id="registro" class="form-row">
				<div class="form-group mr-2">
					<label for="origem">Origem</label>
					<select id="origem" class="form-control" tabindex="-1" name="origem">
						<option selected>Selecione...</option>
						<option>Item 1</option>
						<option>Item 2</option>
						<option>Item 3</option>
					</select>
				</div>
				<div class="form-group mr-2">
					<label for="destino">Destino</label>
					<select id="destino" class="form-control" tabindex="-1" name="destino">
						<option selected>Selecione...</option>
						<option>Item 1</option>
						<option>Item 2</option>
						<option>Item 3</option>
					</select>
				</div>
				<div class="form-group mr-2">
					<label for="item">Item</label>
					<select id="item" class="form-control" tabindex="-1" name="item">
						<option selected>Selecione...</option>
						<option>Item 1</option>
						<option>Item 2</option>
						<option>Item 3</option>
					</select>
				</div>
				<div class="form-group mr-2">
					<label for="hora">Hora</label>
					<input id="hora" type="time" class="form-control" name="hora">
				</div>
				<div class="form-group col-md-1">
					<div class="form-check form-check-inline" style="padding-top: 40px;">
						<input class="form-check-input" type="checkbox" id="bf" value="bf" tabindex="-1">
						<label class="form-check-label" for="bf"><b>BF</b></label>
					</div>
				</div>
			</div>
		</form>
	</div>
	<div class="row">
		<button form="formX" type="submit" class="btn btn-primary mr-3" tabindex="-1">Salvar</button>
		<button class="btn btn-info" onclick="addReg()" tabindex="-1">+</button>
	</div>

</div>


Problems

When I clone, it does not bring the values of the elements select.

Also, keeps the elements label, of course, because I am copying everything. I have tried to remove but could not.

add


Doubts

  • How do I keep the selected value of the elements select?
  • How do I always clone the "last clone"? (I remove the id from the previous one and add it to the cloned one?)
  • How do I delete the elements label (of the type elements input) not to duplicate them?
  • In short: you want the last selected values to be used when cloning and without the Abels?

  • @Andersoncarloswoss that! rs

  • And the "BF", will remove tb?

  • @Sam No, the BF keeps!

4 answers

4


When you do the clone in jQuery, the state of select is not cloned together, so you will need to set the values according to the last selected value. To do so, you can always clone the last item on your list; after you clone you can scroll through all the select and set values according to the cloned item. Finally, you hide all label of the new element and adds it to the DOM.

function addReg() {
  // Pega o último item da lista
  const template = $('#formX > div').last();

  // Faz o clone
  const novo = template.clone();

  // Define os valores dos select conforme o item clonado
  $(template).find('select').each(function(i) {
    $(novo).find("select").eq(i).val($(this).val());
  });

  // Oculta os labels
  novo.find('label').hide();

  // Mantém os labels dos checkbox
  novo.find('input[type=checkbox] + label').show();

  // Adiciona o elemento na DOM
  $('#formX').append(novo);
}

See working:

function addReg() {
  const template = $('#formX > div').last();
  const novo = template.clone();
  
  $(template).find('select').each(function(i) {
    $(novo).find("select").eq(i).val($(this).val());
  });
  
  novo.find('label').hide();
  novo.find('input[type=checkbox] + label').show();
  
  $('#formX').append(novo);
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="container">
  <div class="row">
    <form id="formX" method="get" action="kk.php">
      <div class="form-row">
        <div class="form-group mr-2">
          <label for="origem">Origem</label>
          <select class="form-control" tabindex="-1" name="origem">
            <option selected>Selecione...</option>
            <option>Item 1</option>
            <option>Item 2</option>
            <option>Item 3</option>
          </select>
        </div>
        <div class="form-group mr-2">
          <label for="destino">Destino</label>
          <select class="form-control" tabindex="-1" name="destino">
            <option selected>Selecione...</option>
            <option>Item 1</option>
            <option>Item 2</option>
            <option>Item 3</option>
          </select>
        </div>
        <div class="form-group mr-2">
          <label for="item">Item</label>
          <select class="form-control" tabindex="-1" name="item">
            <option selected>Selecione...</option>
            <option>Item 1</option>
            <option>Item 2</option>
            <option>Item 3</option>
          </select>
        </div>
        <div class="form-group mr-2">
          <label for="hora">Hora</label>
          <input type="time" class="form-control" name="hora">
        </div>
        <div class="form-group col-md-1">
          <div class="form-check form-check-inline" style="padding-top: 40px;">
            <input class="form-check-input" type="checkbox" value="bf" tabindex="-1">
            <label class="form-check-label" for="bf"><b>BF</b></label>
          </div>
        </div>
      </div>
    </form>
  </div>
  <div class="row">
    <button form="formX" type="submit" class="btn btn-primary mr-3" tabindex="-1">Salvar</button>
    <button class="btn btn-info" onclick="addReg()" tabindex="-1">+</button>
  </div>

</div>

3

I made a new Jquery function to make the clone, so you can use it elsewhere in the future, and you may happen to have some similar problem in another element, in case this happens you can change only this function to create a custom clone.

//Criei uma nova função para o Jquery, assim ela pode ser reaproveitada em outros momentos,
//e caso tenha problema ao clonar outro elemento, e só alterar esta função
$.fn.newClone = function(){ 
    var novo = this.clone();
    var self = this;
    novo.find('select').each(function(i) {
      $(this).val($(self).find("select").eq(i).val());
    });
    return novo;
}

function addReg(){
  var novo = $('#formX > div').last().newClone();//Utilizo o novo cloe
  novo.find('label').not('.form-check-label').remove();//E utilizo o "not" para não aplicar a remoção do label para o checkbox
  $('#formX').append(novo);
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="container">
	
	<div class="row">
		<form id="formX" method="get" action="kk.php">
			<div id="registro" class="form-row">
				<div class="form-group mr-2">
					<label for="origem">Origem</label>
					<select id="origem" class="form-control" tabindex="-1" name="origem">
						<option selected>Selecione...</option>
						<option>Item 1</option>
						<option>Item 2</option>
						<option>Item 3</option>
					</select>
				</div>
				<div class="form-group mr-2">
					<label for="destino">Destino</label>
					<select id="destino" class="form-control" tabindex="-1" name="destino">
						<option selected>Selecione...</option>
						<option>Item 1</option>
						<option>Item 2</option>
						<option>Item 3</option>
					</select>
				</div>
				<div class="form-group mr-2">
					<label for="item">Item</label>
					<select id="item" class="form-control" tabindex="-1" name="item">
						<option selected>Selecione...</option>
						<option>Item 1</option>
						<option>Item 2</option>
						<option>Item 3</option>
					</select>
				</div>
				<div class="form-group mr-2">
					<label for="hora">Hora</label>
					<input id="hora" type="time" class="form-control" name="hora">
				</div>
				<div class="form-group col-md-1">
					<div class="form-check form-check-inline" style="padding-top: 40px;">
						<input class="form-check-input" type="checkbox" id="bf" value="bf" tabindex="-1">
						<label class="form-check-label" for="bf"><b>BF</b></label>
					</div>
				</div>
			</div>
		</form>
	</div>
	<div class="row">
		<button form="formX" type="submit" class="btn btn-primary mr-3" tabindex="-1">Salvar</button>
		<button class="btn btn-info" onclick="addReg()" tabindex="-1">+</button>
	</div>

</div>

2

Try to accomplish it this way:

function addReg(){
  var ultimo = $('#formX > div').last();
  var novo = ultimo.clone();
  
  //Seleciona os valores do ultimo clone e seta no novo clone
  novo.find("#origem").val(ultimo.find("#origem").val());
  novo.find("#destino").val(ultimo.find("#destino").val());
  novo.find("#item").val(ultimo.find("#item").val());  
  
  //Remove todos os labels do clone menos o BF
  novo.find('label').not('.form-check-label').remove();
    
  $('#formX').append(novo);
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="container">
	
	<div class="row">
		<form id="formX" method="get" action="kk.php">
			<div id="registro" class="form-row">
				<div class="form-group mr-2">
					<label for="origem">Origem</label>
					<select id="origem" class="form-control" tabindex="-1" name="origem">
						<option selected>Selecione...</option>
						<option>Item 1</option>
						<option>Item 2</option>
						<option>Item 3</option>
					</select>
				</div>
				<div class="form-group mr-2">
					<label for="destino">Destino</label>
					<select id="destino" class="form-control" tabindex="-1" name="destino">
						<option selected>Selecione...</option>
						<option>Item 1</option>
						<option>Item 2</option>
						<option>Item 3</option>
					</select>
				</div>
				<div class="form-group mr-2">
					<label for="item">Item</label>
					<select id="item" class="form-control" tabindex="-1" name="item">
						<option selected>Selecione...</option>
						<option>Item 1</option>
						<option>Item 2</option>
						<option>Item 3</option>
					</select>
				</div>
				<div class="form-group mr-2">
					<label for="hora">Hora</label>
					<input id="hora" type="time" class="form-control" name="hora">
				</div>
				<div class="form-group col-md-1">
					<div class="form-check form-check-inline" style="padding-top: 40px;">
						<input class="form-check-input" type="checkbox" id="bf" value="bf" tabindex="-1">
						<label class="form-check-label" for="bf"><b>BF</b></label>
					</div>
				</div>
			</div>
		</form>
	</div>
	<div class="row">
		<button form="formX" type="submit" class="btn btn-primary mr-3" tabindex="-1">Salvar</button>
		<button class="btn btn-info" onclick="addReg()" tabindex="-1">+</button>
	</div>

</div>

  • 1

    Albertt, is not cloning the previous record, he only clones the first...

  • Correction applied!

1

When cloning the element, it will repeat the id’s of the child elements. This solution will remove all repeated id’s and keep clicking on label checkbox BF creating a id and a for unique to each, maintaining its functionality:

Another detail I noticed is changing the name's for array if available that send pro backend by adding the brackets []. Ex.: name="origem[], name="destino[]" etc....

Solution:

function addReg(){
   
   //conta a quantidade de linhas
   var novo_id = $("#formX > .form-row").length;
   
   // seleciona a última linha
   var reg = $("#formX .form-row:last");

   // clona o elemento e remove o id
   var clone = reg.clone().removeAttr("id");

   // remove os ids dos selects
   clone.find("select").removeAttr("id");

   // atribui novo id ao checkbox do "BF"
   clone.find("input:last").attr("id", "bf"+novo_id);

   // atribui novo "for" ao label do "BF"
   clone.find("label:last").attr("for", "bf"+novo_id);

   // remove todos os labels, menos o último, que é o "BF"
   clone.find("label:not(:last)").remove();
   
   // percorre todos os últimos elementos de cada .form-group
   // da última linha
   $("#formX .form-row:last .form-group *:last-child").each(function(){
      clone
      .find("[name='"+ $(this).attr("name") +"']") // busca o elemento com o mesmo name
      .val( $(this).val() ); // altera o respectivo elemento no clone
   });

   // insere o clone no form
   $("#formX").append(clone);
      
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
	
	<div class="row">
		<form id="formX" method="get" action="kk.php">
			<div id="registro" class="form-row">
				<div class="form-group mr-2">
					<label for="origem">Origem</label>
					<select id="origem" class="form-control" tabindex="-1" name="origem[]">
						<option selected>Selecione...</option>
						<option>Item 1</option>
						<option>Item 2</option>
						<option>Item 3</option>
					</select>
				</div>
				<div class="form-group mr-2">
					<label for="destino">Destino</label>
					<select id="destino" class="form-control" tabindex="-1" name="destino[]">
						<option selected>Selecione...</option>
						<option>Item 1</option>
						<option>Item 2</option>
						<option>Item 3</option>
					</select>
				</div>
				<div class="form-group mr-2">
					<label for="item">Item</label>
					<select id="item" class="form-control" tabindex="-1" name="item[]">
						<option selected>Selecione...</option>
						<option>Item 1</option>
						<option>Item 2</option>
						<option>Item 3</option>
					</select>
				</div>
				<div class="form-group mr-2">
					<label for="hora">Hora</label>
					<input id="hora" type="time" class="form-control" name="hora[]">
				</div>
				<div class="form-group col-md-1">
					<div class="form-check form-check-inline" style="padding-top: 40px;">
						<input class="form-check-input" type="checkbox" id="bf" value="bf" tabindex="-1">
						<label class="form-check-label" for="bf"><b>BF</b></label>
					</div>
				</div>
			</div>
		</form>
	</div>
	<div class="row">
		<button form="formX" type="submit" class="btn btn-primary mr-3" tabindex="-1">Salvar</button>
		<button class="btn btn-info" onclick="addReg()" tabindex="-1">+</button>
	</div>

</div>

Browser other questions tagged

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