Estoy usando Bootstrap y lo siguiente no funciona:
<tbody>
<a href="#">
<tr>
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
</tr>
</a>
</tbody>
Estoy usando Bootstrap y lo siguiente no funciona:
<tbody>
<a href="#">
<tr>
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
</tr>
</a>
</tbody>
Respuestas:
Mire otras respuestas a continuación, especialmente las que no usan jquery.
Preservado para la posteridad, pero seguramente el enfoque equivocado en 2020. (No era idiomático incluso en 2017)
Está utilizando Bootstrap, lo que significa que está utilizando jQuery: ^), por lo que una forma de hacerlo es:
<tbody>
<tr class='clickable-row' data-href='url://'>
<td>Blah Blah</td> <td>1234567</td> <td>£158,000</td>
</tr>
</tbody>
jQuery(document).ready(function($) {
$(".clickable-row").click(function() {
window.location = $(this).data("href");
});
});
Por supuesto, no tiene que usar href o cambiar ubicaciones, puede hacer lo que quiera en la función de controlador de clic. Siga leyendo jQuery
y cómo escribir controladores;
La ventaja de usar una clase sobre la identificación es que puede aplicar la solución a varias filas:
<tbody>
<tr class='clickable-row' data-href='url://link-for-first-row/'>
<td>Blah Blah</td> <td>1234567</td> <td>£158,000</td>
</tr>
<tr class='clickable-row' data-href='url://some-other-link/'>
<td>More money</td> <td>1234567</td> <td>£800,000</td>
</tr>
</tbody>
y su base de código no cambia. El mismo controlador se encargaría de todas las filas.
Puede usar las devoluciones de llamada Bootstrap jQuery de esta manera (en una document.ready
devolución de llamada):
$("#container").on('click-row.bs.table', function (e, row, $element) {
window.location = $element.data('href');
});
Esto tiene la ventaja de que no se restablece al ordenar la tabla (lo que sucede con la otra opción).
Dado que esto se publicó window.document.location
es obsoleto (o en desuso, como mínimo), use window.location
en su lugar.
href
atributo en un tr
, ya que no es un atributo válido para este elemento. Utilice los atributos de datos en su lugar: data-url="{linkurl}"
y en el código js:$(this).data('url')
clickable_row
(CamelCase está en contra de los estándares HTML y debería estar en minúsculas (tuve problemas con el navegador cruzado varias veces con esto)) y luego jQuery es $('.clickable_row tr').click(function ...
Pero realmente deberías estar usando data-
para retener datos, en lugar de href
porque esa es la especificación para datos personalizados. data-url
y jquery accederá a él como$(this).data(url);
a
etiqueta display: block;
dentro de cada celda es un poco molesto, pero parece ser la forma más útil de resolver este problema.
No puedes hacer eso. Es HTML inválido. No se puede poner un <a>
entre a <tbody>
y a <tr>
. Intenta esto en su lugar:
<tr onclick="window.location='#';">
...
</tr>
agregar estilo para vista de puntero
[data-href] { cursor: pointer; }
Cuando lo haga, querrá usar JavaScript para asignar el controlador de clics fuera del HTML.
<a>
dentro de la fila cliqueada. (eso también se degradaría con gracia)
onClick={() => window.open('https://stackoverflow.com/', '_blank')}
Podría incluir un ancla dentro de cada <td>
, así:
<tr>
<td><a href="#">Blah Blah</a></td>
<td><a href="#">1234567</a></td>
<td><a href="#">more text</a></td>
</tr>
Luego, puede usar display:block;
los anclajes para hacer clic en la fila completa.
tr:hover {
background: red;
}
td a {
display: block;
border: 1px solid black;
padding: 16px;
}
Probablemente sea lo más óptimo posible, a menos que recurra a JavaScript.
tabindex="-1"
todo menos el primer <td>
enlace, por lo que el usuario tabula fila por fila, no celda por celda. Además, aún puede resaltar / delinear toda la fila si desea utilizar la :focus-within
pseudoclase CSS.
Es posible una fila de tabla vinculada, pero no con los <table>
elementos estándar . Puedes hacerlo usando las display: table
propiedades de estilo. Aquí y aquí hay algunos violines para demostrar.
Este código debería hacer el truco:
.table {
display: table;
}
.row {
display: table-row;
}
.cell {
display: table-cell;
padding: 10px;
}
.row:hover {
background-color: #cccccc;
}
.cell:hover {
background-color: #e5e5e5;
}
<link href="https://stackpath.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet" type="text/css" />
<div role="grid" class="table">
<div role="row" class="row">
<div role="gridcell" class="cell">
1.1
</div>
<div role="gridcell" class="cell">
1.2
</div>
<div role="gridcell" class="cell">
1.3
</div>
</div>
<a role="row" class="row" href="#">
<div role="gridcell" class="cell">
2.1
</div>
<div role="gridcell" class="cell">
2.2
</div>
<div role="gridcell" class="cell">
2.3
</div>
</a>
</div>
Tenga en cuenta que los roles ARIA son necesarios para garantizar la accesibilidad adecuada, ya que los <table>
elementos estándar no se utilizan. Es posible que deba agregar roles adicionales como, role="columnheader"
si corresponde. Obtenga más información en la guía aquí.
/
clave en Firefox), navegación ( tab
clave), Copiar ubicación del enlace, Abrir en una nueva pestaña / ventana, etc., incluso para acceso / especial necesita navegadores Mi único inconveniente es que no anidaría <div>
dentro <a>
, por lo que las celdas estarían mejor marcadas como <span>
.
_tables.scss
y algunas otras piezas aleatorias, reemplazando todas las apariciones de elementos de la tabla con las clases CSS que elegí usar (que son simplemente las mismas que los elementos: th
→ .th
) No mucho trabajo en comparación con los beneficios, realmente .
<table>
está ahí por una razón. Pero esto todavía supera cualquier solución de JavaScript :)
Logrado usando Bootstrap 4.3+ estándar de la siguiente manera: ¡no se necesitan jQuery ni ninguna clase de CSS adicional!
La clave es usar stretched-link
el texto dentro de la celda y definirlo <tr>
como un bloque contenedor.
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<table class="table table-hover">
<tbody>
<tr style="transform: rotate(0);">
<th scope="row"><a href="#" class="stretched-link">1</a></th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
Puede definir que contiene el bloque de diferentes maneras, por ejemplo, estableciendo transform
un valor que no sea ninguno (como en el ejemplo anterior).
Para obtener más información, lea aquí la documentación de Bootstrap para stretched-link
.
scope="row"
? No uso el alcance y la fila todavía se comporta como un enlace.
scope="row"
- revise el historial si desea ver qué más puede haber sido editado. Sin embargo, no revertí las ediciones, ya que el fragmento de código parece funcionar (como lo hizo el original) y no tuve la oportunidad de probar el nuevo código exhaustivamente :-)
tr
etiqueta que no se reconoce como las reglas para el bloque de contención entre los navegadores ... stackoverflow.com/questions/61342248/…
stretched-link
.
Una solución mucho más flexible es apuntar a cualquier cosa con el atributo data-href. Esto es, puede reutilizar el código fácilmente en diferentes lugares.
<tbody>
<tr data-href="https://google.com">
<td>Col 1</td>
<td>Col 2</td>
</tr>
</tbody>
Luego, en su jQuery solo apunte a cualquier elemento con ese atributo:
jQuery(document).ready(function($) {
$('*[data-href]').on('click', function() {
window.location = $(this).data("href");
});
});
Y no olvides diseñar tu CSS:
[data-href] {
cursor: pointer;
}
Ahora puede agregar el atributo data-href a cualquier elemento y funcionará. Cuando escribo fragmentos como este, me gusta que sean flexibles. Siéntase libre de agregar una solución vainilla js a esto si tiene una.
Puede usar este componente de arranque:
http://jasny.github.io/bootstrap/javascript/#rowlink
Los componentes que faltan para su marco front-end favorito.
<table class="table table-striped table-bordered table-hover">
<thead>
<tr><th>Name</th><th>Description</th><th>Actions</th></tr>
</thead>
<tbody data-link="row" class="rowlink">
<tr><td><a href="#inputmask">Input mask</a></td><td>Input masks can be used to force the user to enter data conform a specific format.</td><td class="rowlink-skip"><a href="#">Action</a></td></tr>
<tr><td><a href="http://www.jasny.net/" target="_blank">jasny.net</a></td><td>Shared knowledge of Arnold Daniels aka Jasny.</td><td class="rowlink-skip"><a href="#">Action</a></td></tr>
<tr><td><a href="#rowlinkModal" data-toggle="modal">Launch modal</a></td><td>Toggle a modal via JavaScript by clicking this row.</td><td class="rowlink-skip"><a href="#">Action</a></td></tr>
</tbody>
</table>
Agregue clase .rowlink
y atributo data-link="row"
a un elemento <table>
o <tbody>
. Para otras opciones, agregue el nombre a los datos, ya que en data-target="a.mainlink"
una celda se puede excluir agregando la .rowlink-skip
clase a <td>
.
Llame a la máscara de entrada a través de javascript:
$('tbody.rowlink').rowlink()
Hay una buena manera de hacerlo técnicamente con la <a>
etiqueta dentro <tr>
, que puede ser semánticamente incorrecta (puede que le dé una advertencia al navegador), pero funcionará sin JavaScript/jQuery
necesidad:
<!-- HTML -->
<tbody>
<tr class="bs-table-row">
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
<a class="bs-row-link" href="/your-link-here"></a>
</tr>
</tbody>
/* CSS */
.bs-table-row {
position: 'relative';
}
.bs-row-link {
position: 'absolute';
left: 0;
height: '36px'; // or different row height based on your requirements
width: '100%';
cursor: 'pointer';
}
PD: Observe que el truco aquí es colocar la <a>
etiqueta como último elemento, de lo contrario, tratará de ocupar el espacio de la primera <td>
celda.
PPS: Ahora se podrá hacer clic en toda su fila y también puede usar este enlace para abrir en una pestaña nueva (Ctrl / CMD + clic)
<tr>
elementos no pueden tener un <a>
elemento como niño. Solo <td>
y <th>
son niños válidos. Ver: stackoverflow.com/questions/12634715/…
Puede usar el método onclick javascript en tr y hacer que se pueda hacer clic, también si necesita construir su enlace debido a algunos detalles, puede declarar una función en javascript y llamarlo en onclick, pasando algunos valores.
Aquí hay una manera de poner un elemento A transparente sobre las filas de la tabla. Las ventajas son:
Desventajas
La tabla se queda como está:
<table id="tab1">
<tbody>
<tr>
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
</tr>
</tbody>
</table>
Agregue los enlaces (para cada fila) a través de jQuery JavaScript insertando un elemento A en cada primera columna y estableciendo las propiedades necesarias:
// v1, fixed for IE and Chrome
// v0, worked on Firefox only
// width needed for adjusting the width of the A element
var mywidth=$('#tab1').width();
$('#tab1 tbody>tr>td:nth-child(1)').each(function(index){
$(this).css('position', 'relative');// debug: .css('background-color', '#f11');
// insert the <A> element
var myA=$('<A>');
$(this).append(myA);
var myheight=$(this).height();
myA.css({//"border":'1px solid #2dd', border for debug only
'display': 'block',
'left': '0',
'top': '0',
'position': 'absolute'
})
.attr('href','the link here')
.width(mywidth)
.height(myheight)
;
});
El ajuste de ancho y alto puede ser complicado, si se utilizan muchos rellenos y márgenes, pero en general, unos pocos píxeles de distancia ni siquiera deberían importar.
Demostración en vivo aquí: http://jsfiddle.net/qo0dx0oo/ (funciona en Firefox, pero no en IE o Chrome, allí el enlace está mal colocado)
Corregido para Chrome e IE (todavía funciona en FF también): http://jsfiddle.net/qo0dx0oo/2/
onmouseover
Puede agregar la función de botón a una fila de la tabla y Bootstrap cambiará el cursor sin ningún cambio de CSS. Decidí usar ese rol como una forma de hacer que cualquier fila sea clicable con muy poco código.
HTML
<table class="table table-striped table-hover">
<tbody>
<tr role="button" data-href="#">
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
</tbody>
</table>
jQuery
$(function(){
$(".table").on("click", "tr[role=\"button\"]", function (e) {
window.location = $(this).data("href");
});
});
Puede aplicar este mismo principio para agregar la función de botón a cualquier etiqueta.
Este código debajo hará que se pueda hacer clic en toda la tabla. Al hacer clic en los enlaces de este ejemplo, se mostrará el enlace en un cuadro de diálogo de alerta en lugar de seguir el enlace.
El HTML:
Aquí está el HTML detrás del ejemplo anterior:
<table id="example">
<tr>
<th> </th>
<th>Name</th>
<th>Description</th>
<th>Price</th>
</tr>
<tr>
<td><a href="apples">Edit</a></td>
<td>Apples</td>
<td>Blah blah blah blah</td>
<td>10.23</td>
</tr>
<tr>
<td><a href="bananas">Edit</a></td>
<td>Bananas</td>
<td>Blah blah blah blah</td>
<td>11.45</td>
</tr>
<tr>
<td><a href="oranges">Edit</a></td>
<td>Oranges</td>
<td>Blah blah blah blah</td>
<td>12.56</td>
</tr>
</table>
El CSS
Y el CSS:
table#example {
border-collapse: collapse;
}
#example tr {
background-color: #eee;
border-top: 1px solid #fff;
}
#example tr:hover {
background-color: #ccc;
}
#example th {
background-color: #fff;
}
#example th, #example td {
padding: 3px 5px;
}
#example td:hover {
cursor: pointer;
}
El jQuery
Y finalmente el jQuery que hace que la magia suceda:
$(document).ready(function() {
$('#example tr').click(function() {
var href = $(this).find("a").attr("href");
if(href) {
window.location = href;
}
});
});
Lo que hace es que cuando se hace clic en una fila, se realiza una búsqueda de la href que pertenece a un ancla. Si se encuentra uno, la ubicación de la ventana se establece en esa href.
Una opción muy fácil es simplemente usar al hacer clic, y más correcto, en mi punto de vista, porque esto separa la vista y el controlador, y no necesita codificar la URL o lo que sea que necesite hacer con el clic . Funciona con Angular ng-click también.
<table>
<tr onclick="myFunction(this)">
<td>Click to show rowIndex</td>
</tr>
</table>
<script>
function myFunction(x) {
alert("Row index is: " + x.rowIndex);
}
</script>
Ejemplo trabajando aquí
Otra opción usando un <a>
, posiciones CSS y algunos jQuery o JS :
HTML:
<table>
<tr>
<td>
<span>1</span>
<a href="#" class="rowLink"></a>
</td>
<td><span>2</span></td>
</tr>
</table>
CSS:
table tr td:first-child {
position: relative;
}
a.rowLink {
position: absolute;
top: 0; left: 0;
height: 30px;
}
a.rowLink:hover {
background-color: #0679a6;
opacity: 0.1;
}
Luego debe dar un ancho, usando por ejemplo jQuery:
$(function () {
var $table = $('table');
$links = $table.find('a.rowLink');
$(window).resize(function () {
$links.width($table.width());
});
$(window).trigger('resize');
});
Sé que alguien ya ha escrito más o menos lo mismo, sin embargo, mi forma es la correcta (div no puede ser hijo de A) y también es mejor usar clases.
Puede imitar una tabla usando CSS y hacer que un elemento A sea la fila
<div class="table" style="width:100%;">
<a href="#" class="tr">
<span class="td">
cell 1
</span>
<span class="td">
cell 2
</span>
</a>
</div>
css:
.table{display:table;}
.tr{display:table-row;}
.td{display:table-cell;}
.tr:hover{background-color:#ccc;}
La respuesta aceptada es excelente, pero propongo una pequeña alternativa si no desea repetir la URL en cada tr. Entonces pones la url o href en la tabla data-url y no el tr.
<table data-click data-url="href://blah">
<tbody>
<tr id ="2">
<td>Blah Blah</td> <td>1234567</td> <td>£158,000</td>
</tr>
<tr id ="3">
<td>Blah Blah</td> <td>1234567</td> <td>£158,000</td>
</tr>
</tbody>
</table
jQuery(document).ready(function($) {
$('[data-click] tbody tr').click(function() {
var url = $(this).closest('table').data("url");
var id = $(this).closest('tr').attr('id');
window.location = url+"?id="+id);
});
});
Esto también es bueno porque tampoco necesita agregar el atributo de datos de clic a cada tr. La otra cosa buena es que no estamos usando una clase para activar un clic, ya que las clases solo deberían usarse para diseñar.
Una solución que no se mencionó anteriormente es usar un solo enlace en una celda y algo de CSS para extender este enlace sobre las celdas:
table {
border: 1px solid;
width: 400px;
overflow: hidden;
}
tr:hover {
background: gray;
}
tr td {
border: 1px solid;
}
tr td:first-child {
position:relative;
}
a:before {
content: '';
position:absolute;
left: 0;
top: 0;
bottom: 0;
display: block;
width: 400px;
}
<table>
<tr>
<td><a href="https://google.com">First column</a></td>
<td>Second column</td>
<td>Third column</td>
</tr>
<tr>
<td><a href="https://stackoverflow.com">First column</a></td>
<td>Second column</td>
<td>Third column</td>
</tr>
</table>
<tbody>
<tr data-href='www.bbc.co.uk'>
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
</tr>
<tr data-href='www.google.com'>
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
</tr>
</tbody>
<script>
jQuery(document).ready(function ($) {
$('[data-href]').click(function () {
window.location = $(this).data("href");
});
});
</script>
Si bien la solución principal aquí es excelente, mi solución elimina la necesidad de clases. Todo lo que necesita hacer es agregar el atributo data-href con la URL.
He invertido mucho tiempo tratando de resolver este problema.
Hay 3 enfoques:
Utiliza JavaScript. Los inconvenientes claros: no es posible abrir una nueva pestaña de forma nativa, y al pasar el cursor sobre la fila no habrá ninguna indicación en la barra de estado como los enlaces regulares. La accesibilidad también es una pregunta.
Use solo HTML / CSS. Esto significa poner <a>
anidados debajo de cada uno <td>
. Un enfoque simple como este violín no funciona, porque la superficie en la que se puede hacer clic no es necesariamente igual para cada columna. Esta es una seria preocupación de UX. Además, si necesita un <button>
en la fila, no es HTML válido anidarlo bajo la <a>
etiqueta (aunque los navegadores están bien con eso).
He encontrado otras 3 formas de implementar este enfoque. Primero está bien, los otros dos no son geniales.
a) Echa un vistazo a este ejemplo :
tr {
height: 0;
}
td {
height: 0;
padding: 0;
}
/* A hack to overcome differences between Chrome and Firefox */
@-moz-document url-prefix() {
td {
height: 100%;
}
}
a {
display: block;
height: 100%;
}
Funciona, pero debido a las inconsistencias entre Chrome y Firefox, requiere un hack específico del navegador para superar las diferencias. Además, Chrome siempre alineará el contenido de la celda en la parte superior, lo que puede causar problemas con textos largos, especialmente si hay alturas de línea variables.
b) Configuración <td>
a { display: contents; }
. Esto lleva a otros 2 problemas:
b1. Si alguien más intenta <td>
darle estilo directamente a la etiqueta, como configurarla { width: 20px; }
, debemos pasar ese estilo de alguna manera a la <a>
etiqueta. Necesitamos algo de magia para hacer eso, probablemente más magia que en la alternativa de Javascript.
b2. { display: contents; }
sigue siendo experimental; específicamente no es compatible con Edge.
c) Configuración <td>
a { height: --some-fixed-value; }
. Esto simplemente no es lo suficientemente flexible.
El último enfoque, que recomiendo pensar seriamente, es no usar filas en las que se pueda hacer clic . Las filas en las que se puede hacer clic no son una gran experiencia de UX: no es fácil marcarlas visualmente como clicables, y plantea desafíos cuando se puede hacer clic en varias partes dentro de las filas, como los botones. Por lo tanto, una alternativa viable podría ser tener una <a>
etiqueta solo en la primera columna, mostrada como un enlace regular, y darle la función de navegar por toda la fila.
Aquí hay otra forma ...
El HTML:
<table>
<tbody>
<tr class='clickableRow'>
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
</tr>
</tbody>
</table>
El jQuery:
$(function() {
$(".clickableRow").on("click", function() {
location.href="http://google.com";
});
});
Podría darle a la fila una identificación, por ejemplo
<tr id="special"> ... </tr>
y luego usa jquery para decir algo como:
$('#special').onclick(function(){ window="http://urltolinkto.com/x/y/z";})
¿Por qué no deberíamos usar etiquetas "div" ...
<div>
<a href="" > <div> Table row of content here.. </div> </a>
</div>