Get clicked item position

6

I have a list with registered items and one of the attributes of this item is a button to delete that item.

By clicking on the button I want to know the position of the line clicked inside the list.

When I know the position, I'll delete the same value from the array as posição[i]

removeLinha(element){
    //Aqui eu obtenho a 'tr' clicada
    let trash = element.parentNode.parentNode; 

    //Aqui eu removo;
    trash.parentNode.removeChild(trash);
}

But before removing I need to know the position of <tr> within <tbody> to delete in array too.

The problem is that the method of adding a new row in the DOM it scans an array of objects and places it in the DOM, so I need to know the position of the row to know its position in the array and delete also.

    
asked by anonymous 01.11.2017 / 19:41

5 answers

1

You can use .closest('tr') to fetch tr and then .indexOf( .

For example:

function removeLinha(element) {
  const trash = element.closest('tr');
  const index = [...trash.parentNode.children].indexOf(trash);
  trash.parentNode.removeChild(trash);


  console.log('Index era:', index); // só para o exemplo
}
tr td:last-of-type:hover { color: #e88; }
<table id="codexpl">
  <tr>
    <td>1</td>
    <td>This</td>
    <td>Column</td>
    <td onclick="removeLinha(this)">Remove</td>
  </tr>
  <tr>
    <td>2</td>
    <td>Coloumn</td>
    <td>two</td>
    <td onclick="removeLinha(this)">Remove</td>
  </tr>
  <tr>
    <td>3</td>
    <td>is</td>
    <td>not equals</td>
    <td onclick="removeLinha(this)">Remove</td>
  </tr>
  <tr>
    <td>4</td>
    <td>the</td>
    <td>Column</td>
    <td onclick="removeLinha(this)">Remove</td>
  </tr>
  <tr>
    <td>5</td>
    <td>first</td>
    <td>One</td>
    <td onclick="removeLinha(this)">Remove</td>
  </tr>
</table>
    
01.11.2017 / 23:26
2

With these pure JS, you get the index position of the clicked button row and delete the line.

Using eventListener :

window.onload = escuta;

botoes = document.getElementsByClassName("apagar");
function escuta(){
  for(x=0;x<botoes.length;x++){
    // arranjo os listeners com os index das linhas
    (function(index){
      botoes[x].addEventListener("click", function(){
        removeLinha(index);
      });
    })(x);
  }
}
	
function removeLinha(element){ // element é o index da linha clicada
   console.log(element); // mostrar index da linha como exemplo
  //removo a linha
  botoes[element].closest('tr').outerHTML = '';
  // removo os listeners
  for(x=0;x<botoes.length;x++){
    objclone = botoes[x].cloneNode(true);
    botoes[x].parentNode.replaceChild(objclone, botoes[x]);
  }
  escuta();
}
<table>
    <tr>
      <td>Linha 1</td>
      <td><input class="apagar" type="button" value="X" /></td>
    </tr>
    <tr>
      <td>Linha 2</td>
      <td><input class="apagar" type="button" value="X" /></td>
    </tr>
    <tr>
      <td>Linha 3</td>
      <td><input class="apagar" type="button" value="X" /></td>
    </tr>
    <tr>
      <td>Linha 4</td>
      <td><input class="apagar" type="button" value="X" /></td>
    </tr>
</table>

Using onclick :

function removeLinha(element){
  var el = element.closest('tr');
  var index = Array.prototype.indexOf.call(el.parentNode.children, el);
  console.log(index); // mostrar posição da linha como exemplo
  //removo a linha
  el.outerHTML = '';
}
<table>
    <tr>
      <td>Linha 1</td>
      <td><input class="apagar" type="button" value="X" onclick="removeLinha(this)" /></td>
    </tr>
    <tr>
      <td>Linha 2</td>
      <td><input class="apagar" type="button" value="X" onclick="removeLinha(this)" /></td>
    </tr>
    <tr>
      <td>Linha 3</td>
      <td><input class="apagar" type="button" value="X" onclick="removeLinha(this)" /></td>
    </tr>
    <tr>
      <td>Linha 4</td>
      <td><input class="apagar" type="button" value="X" onclick="removeLinha(this)" /></td>
    </tr>
</table>
    
01.11.2017 / 22:53
1

An alternative is to use rowIndex , which takes the actual position of the element in DOM , just reference it with this, example.

var arr = ['tr1','tr2'];

var tr = document.querySelectorAll("tr");

for(var i=0; i<tr.length; i++){
  tr[i].onclick = function(){ 
      index = this.rowIndex;
      if(arr[index]) arr.splice(index, 1);
      this.parentElement.removeChild(this);
      console.log('tr clicada, posição ' + index + ' / arr: ' + arr);
 }
}
<table>
  <tr id="tr1">
    <td>teste</td>
    <td>teste1</td>
    <td>teste2</td>
  </tr>
  <tr id="tr2">
    <td>teste3</td>
    <td>teste4</td>
  </tr>
</table>
    
01.11.2017 / 20:35
0

To get the index, you can use indexOf over children .

var btsApagar = document.querySelectorAll(".apagar");
var onApagarClick = function (evt) {
  var linha = this.parentElement.parentElement;
  var nodes = [].slice.call(linha.parentElement.children, 0);
  var index = nodes.indexOf(linha);
  console.log(index);
};

[].forEach.call(btsApagar, function (apagar, indice) {
  apagar.addEventListener("click", onApagarClick);
});
<table>
  <thead>
    <tr>
      <th>Coluna 01</th>
      <th>Coluna 02</th>
      <th>Ações</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Valor 1.1</td>
      <td>Valor 1.2</td>
      <td><input class="apagar" type="button" value="Apagar" /></td>
    </tr>
    <tr>
      <td>Valor 2.1</td>
      <td>Valor 2.2</td>
      <td><input class="apagar" type="button" value="Apagar" /></td>
    </tr>
    <tr>
      <td>Valor 3.1</td>
      <td>Valor 3.2</td>
      <td><input class="apagar" type="button" value="Apagar" /></td>
    </tr>
  </tbody>
</table>

but it might be interesting to use some library to help keep the DOM and array synchronized.

var app = new Vue({
  el: '#tabela',
  data: {
    lista: [
      { valor1: "Valor 1.1", valor2: "Valor 1.2" },
      { valor1: "Valor 2.1", valor2: "Valor 2.2" },
      { valor1: "Valor 3.1", valor2: "Valor 3.2" },
      { valor1: "Valor 4.1", valor2: "Valor 4.2" },
      { valor1: "Valor 5.1", valor2: "Valor 5.2" },
      { valor1: "Valor 6.1", valor2: "Valor 6.2" },
    ]
  },
  methods: {
    apagar: function (item) {
      var index = this.lista.indexOf(item);
      this.lista.splice(index, 1);
      console.log(index);
    } 
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.2/vue.js"></script><tableid="tabela">
  <thead>
    <tr>
      <th>Coluna 01</th>
      <th>Coluna 02</th>
      <th>Ações</th>
    </tr>
  </thead>
  <tbody>
    <tr v-for="item in lista">
      <td>{{item.valor1}}</td>
      <td>{{item.valor2}}</td>
      <td><input type="button" value="Apagar" v-on:click="apagar(item)" /></td>
    </tr>
  </tbody>
</table>
    
01.11.2017 / 21:16
0

Assuming you select a tr and then click a button to delete.

Here's the example (I used jquery because I'm already used to the code, but just adapt the logic):

$(document).ready(function() {
  var tid = "";
  $('#sua_tabela tr').click(function(event) {
    tid = $(this).attr('id');
  });
  $("#del").click(function() {
    console.log(tid);
    if ($('#' + tid).length) {
      $('#' + tid).remove();
    }
  });
});

Explaining:
I store the tr you selected in a variable. When I click the delete button it removes the tr selected, to remove more than 1 just create an array, put every 1 of the selected ones inside the array and click the delete make a for by traversing this array. Or to remove directly when clicking on tr, use this example of a gringo:
link

    
01.11.2017 / 19:49