javascript - validacion - ¿Cómo saber en qué número de fila se hace clic en una tabla?
validacion de formularios con javascript ejemplos (6)
Tengo una tabla como la siguiente:
<table>
<tr>
<td>1</td><td>1</td><td>1</td>
</tr>
<tr>
<td>2</td><td>2</td><td>2</td>
</tr>
<tr>
<td>3</td><td>3</td><td>3</td>
</tr>
</table>
Cuando un usuario hace clic en la tabla, ¿cómo puedo obtener el índice de esta fila (elemento tr
)?
Por ejemplo, cuando hago clic en el primer tr
(con 1
s en la tabla anterior), debería recogerlo y devolver 1
.
En algunos casos, podríamos tener un par de tablas, y luego necesitamos detectar el clic solo para una tabla en particular. Mi solución es la siguiente:
<table id="elitable" border="1" cellspacing="0" width="100%">
<tr>
<td>100</td><td>AAA</td><td>aaa</td>
</tr>
<tr>
<td>200</td><td>BBB</td><td>bbb</td>
</tr>
<tr>
<td>300</td><td>CCC</td><td>ccc</td>
</tr>
</table>
<script>
$(function(){
$("#elitable tr").click(function(){
alert (this.rowIndex);
});
});
</script>
Esto le daría el índice de la fila en la que se hizo clic, comenzando con uno:
$(''#thetable'').find(''tr'').click( function(){
alert(''You clicked row ''+ ($(this).index()+1) );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="thetable">
<tr>
<td>1</td><td>1</td><td>1</td>
</tr>
<tr>
<td>2</td><td>2</td><td>2</td>
</tr>
<tr>
<td>3</td><td>3</td><td>3</td>
</tr>
</table>
Si desea devolver el número almacenado en esa primera celda de cada fila:
$(''#thetable'').find(''tr'').click( function(){
var row = $(this).find(''td:first'').text();
alert(''You clicked '' + row);
});
Puede usar la propiedad object.rowIndex
que tiene un índice que comienza en 0.
$("table tr").click(function(){
alert (this.rowIndex);
});
Ver una demostración de trabajo
Un mejor enfoque sería delegar el evento, lo que significa atraparlo a medida que burbujea en el nodo principal.
delegación - resumen
Esta solución es a la vez más robusta y eficiente.
Permite que el evento se maneje incluso si se agregan dinámicamente más filas a la tabla más adelante y también da como resultado la conexión de un solo controlador de eventos al nodo principal (elemento de table
), en lugar de uno para cada nodo secundario (elemento tr
).
Suponiendo que el ejemplo del OP sea simplificado, la estructura de la tabla puede ser más compleja, por ejemplo:
<table id="indexedTable">
...
<tr>
<td><p>1</p></td>
<td>2</td>
<td><p>3</p></td>
</tr>
</table>
Por lo tanto, un enfoque simplista como obtener e.target.parentElement
no funcionará, ya que al hacer clic en el botón interno <p>
y al hacer clic en el centro <td>
obtendrán resultados diferentes.
El uso de la delegación normaliza el manejo de eventos, solo asumiendo que no hay tablas anidadas.
implementación
Ambos de los siguientes fragmentos son equivalentes:
$("#indexedTable").delegate("tr", "click", function(e) {
console.log($(e.currentTarget).index() + 1);
});
$("#indexedTable").on("click", "tr", function(e) {
console.log($(e.currentTarget).index() + 1);
});
Adjuntan un elemento de escucha al elemento de table
y manejan cualquier evento que burbujee desde las filas de la tabla. La API actual es el método on
y el método delegate
es la API heredada (y en realidad se llama entre bastidores).
Tenga en cuenta que el orden de los parámetros para ambas funciones es diferente.
ejemplo
Una comparación entre el adjunto del controlador directo y la delegación está disponible a continuación o en jsFiddle:
$("#table-delegate").on("click", "tr", function(e) {
var idx = $(e.currentTarget).index() + 1;
$("#delegation-idx").text(idx);
console.log(''delegated'', idx);
});
$("#table-direct tr").on("click", function(e) {
var idx = $(e.currentTarget).index() + 1;
$("#direct-idx").text(idx);
console.log(''direct'', idx);
});
$(''[data-action=add-row]'').click(function(e) {
var id = e.target.dataset.table;
$(''#'' + id + '' tbody'')
.append($(''<tr><td>extra</td><td>extra</td><td>extra</td></tr>'')[0])
});
tr:hover{
background:#ddd;
}
button.add-row {
margin-bottom: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<h1>Event handling test</h1>
<p>Add rows to both tables and see the difference in handling.</p>
<p>Event delegation attaches a single event listener and events related to newly added children are caught.</p>
<p>Direct event handling attaches an event handler to each child, where children added after the inital handler attachment don''t have a handler attached to them, and therefore their indices won''t be logged to console.</p>
<h2>Delegation</h2>
<p><span>row index: </span><span id="delegation-idx">unknown</span></p>
<button class="add-row" data-action="add-row" data-table="table-delegate">Add row to delegation</button>
<table id="table-delegate" class="table">
<tbody>
<tr>
<td>normal</td>
<td>normal</td>
<td>normal</td>
</tr>
<tr>
<td><p>nested</p></td>
<td><p>nested</p></td>
<td><p>nested</p></td>
</tr>
<tr>
<td>normal</td>
<td>normal</td>
<td><p>nested</p></td>
</tr>
</table>
<h2>Direct attachment</h2>
<p><span>row index: </span><span id="direct-idx">unknown</span></p>
<button class="add-row" data-action="add-row" data-table="table-direct">Add row to direct</button>
<table id="table-direct" class="table">
<tbody>
<tr>
<td>normal</td>
<td>normal</td>
<td>normal</td>
</tr>
<tr>
<td><p>nested</p></td>
<td><p>nested</p></td>
<td><p>nested</p></td>
</tr>
<tr>
<td>normal</td>
<td>normal</td>
<td><p>nested</p></td>
</tr>
</tbody>
</table>
Aquí está la demostración en jsFiddle .
PD:
Si tiene tablas anidadas (o, en el caso general, desea delegar a elementos con profundidad específica), puede utilizar esta sugerencia del informe de errores de jQuery .
Una solución simple y gratuita jQuery:
document.querySelector(''#elitable'').onclick = function(ev) {
// ev.target <== td element
// ev.target.parentElement <== tr
var index = ev.target.parentElement.rowIndex;
}
Bonificación: funciona incluso si las filas se agregan / eliminan dinámicamente
$(''tr'').click(function(){
alert( $(''tr'').index(this) );
});
Para el primer tr
, alerta a 0. Si desea alertar a 1, puede agregar 1 al índice.