J'utilise Bootstrap et ce qui suit ne fonctionne pas:
<tbody>
<a href="#">
<tr>
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
</tr>
</a>
</tbody>
J'utilise Bootstrap et ce qui suit ne fonctionne pas:
<tbody>
<a href="#">
<tr>
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
</tr>
</a>
</tbody>
Réponses:
Veuillez consulter les autres réponses ci-dessous, en particulier celles qui n'utilisent pas jquery.
Conservé pour la postérité mais sûrement la mauvaise approche en 2020 (était non idiomatique même en 2017)
Vous utilisez Bootstrap, ce qui signifie que vous utilisez jQuery: ^), donc une façon de le faire est:
<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");
});
});
Bien sûr, vous n'avez pas besoin d'utiliser href ou de changer d'emplacement, vous pouvez faire ce que vous voulez dans la fonction de gestion des clics. Lisez jQuery
et comment écrire des gestionnaires;
L'avantage d'utiliser une classe sur l' ID est que vous pouvez appliquer la solution à plusieurs lignes:
<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>
et votre base de code ne change pas. Le même gestionnaire s'occuperait de toutes les lignes.
Vous pouvez utiliser des rappels Bootstrap jQuery comme ceci (dans un document.ready
rappel):
$("#container").on('click-row.bs.table', function (e, row, $element) {
window.location = $element.data('href');
});
Cela a l'avantage de ne pas être réinitialisé lors du tri des tables (ce qui se produit avec l'autre option).
Étant donné que cela a été publié, son utilisation window.document.location
est obsolète (ou à tout le moins obsolète) window.location
.
href
attribut sur un tr
, car ce n'est pas un attribut valide pour cet élément. Utilisez plutôt des attributs de données: data-url="{linkurl}"
et dans le code js:$(this).data('url')
clickable_row
(CamelCase est contre les normes HTML et devrait être en minuscules (j'ai eu des problèmes avec le navigateur croisé à plusieurs reprises avec cela)), puis la jQuery est $('.clickable_row tr').click(function ...
Mais vous devriez vraiment utiliser data-
pour conserver des données, au lieu de href
puisque c'est la spécification pour les données personnalisées. data-url
et jquery y accèdera comme$(this).data(url);
a
balise avec display: block;
à l'intérieur de chaque cellule est un peu ennuyeux mais cela semble être le moyen le plus utilisable pour résoudre ce problème.
Tu ne peux pas faire ça. Il s'agit d'un code HTML non valide. Vous ne pouvez pas mettre un <a>
entre un <tbody>
et un <tr>
. Essayez plutôt ceci:
<tr onclick="window.location='#';">
...
</tr>
ajouter un style pour la vue du pointeur
[data-href] { cursor: pointer; }
Lorsque vous travaillez dessus, vous souhaitez utiliser JavaScript pour affecter le gestionnaire de clics en dehors du code HTML.
<a>
à l'intérieur de la ligne cliquée. (cela se dégraderait aussi gracieusement)
onClick={() => window.open('https://stackoverflow.com/', '_blank')}
Vous pouvez inclure une ancre à l'intérieur de chaque <td>
, comme ceci:
<tr>
<td><a href="#">Blah Blah</a></td>
<td><a href="#">1234567</a></td>
<td><a href="#">more text</a></td>
</tr>
Vous pouvez ensuite utiliser display:block;
sur les ancres pour rendre la ligne complète cliquable.
tr:hover {
background: red;
}
td a {
display: block;
border: 1px solid black;
padding: 16px;
}
C'est probablement aussi optimal que vous allez l'obtenir, sauf si vous avez recours à JavaScript.
tabindex="-1"
sur tout sauf le premier <td>
lien, donc l'utilisateur tabule ligne par ligne, pas cellule par cellule. De plus, vous pouvez toujours mettre en évidence / décrire la ligne entière si vous souhaitez utiliser la :focus-within
pseudo-classe CSS.
Une ligne de table liée est possible, mais pas avec les <table>
éléments standard . Vous pouvez le faire en utilisant les display: table
propriétés de style. Ici et voici quelques violons à démontrer.
Ce code devrait faire l'affaire:
.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>
Notez que les rôles ARIA sont nécessaires pour assurer une bonne accessibilité puisque les <table>
éléments standard ne sont pas utilisés. Vous devrez peut-être ajouter des rôles supplémentaires, le role="columnheader"
cas échéant. En savoir plus sur le guide ici.
/
clé dans Firefox), navigation ( tab
clé), emplacement du lien de copie, ouverture dans un nouvel onglet / fenêtre, etc. même pour accessible / spécial a besoin de navigateurs. Mon seul pique-nique est que je ne nicherais pas à l' <div>
intérieur d'un <a>
, donc les cellules seraient mieux marquées comme <span>
.
_tables.scss
et quelques autres pièces aléatoires, en remplaçant toutes les occurrences d'éléments de table par les classes CSS que j'ai choisies d'utiliser (qui sont tout simplement les mêmes que les éléments: th
→ .th
) Pas beaucoup de travail par rapport aux avantages, vraiment .
<table>
est là pour une raison. Mais cela bat toujours toute solution javascript :)
Atteint en utilisant Bootstrap 4.3+ standard comme suit - pas de jQuery ni de classes CSS supplémentaires nécessaires!
La clé est d'utiliser stretched-link
sur le texte dans la cellule et de définir <tr>
comme un bloc conteneur.
<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>
Vous pouvez définir le bloc conteneur de différentes manières, par exemple en définissant transform
une valeur non nulle (comme dans l'exemple ci-dessus).
Pour plus d'informations, consultez la documentation Bootstrap pour stretched-link
.
scope="row"
? Je n'utilise pas la portée et la ligne se comporte toujours comme un lien.
scope="row"
- veuillez consulter l'historique si vous souhaitez voir ce qui a pu être modifié. Cependant, je n'ai pas annulé les modifications, car l'extrait de code semble fonctionner (tout comme l'original) et je n'ai pas eu la chance de tester le nouveau code de manière exhaustive :-)
tr
balise qui n'est pas reconnue comme les règles pour le bloc contenant parmi les navigateurs ... stackoverflow.com/questions/61342248/…
stretched-link
.
Une solution beaucoup plus flexible consiste à cibler n'importe quoi avec l'attribut data-href. Vous pouviez ainsi réutiliser facilement le code à différents endroits.
<tbody>
<tr data-href="https://google.com">
<td>Col 1</td>
<td>Col 2</td>
</tr>
</tbody>
Ensuite, dans votre jQuery, ciblez simplement n'importe quel élément avec cet attribut:
jQuery(document).ready(function($) {
$('*[data-href]').on('click', function() {
window.location = $(this).data("href");
});
});
Et n'oubliez pas de styliser votre CSS:
[data-href] {
cursor: pointer;
}
Vous pouvez maintenant ajouter l'attribut data-href à n'importe quel élément et cela fonctionnera. Lorsque j'écris des extraits comme celui-ci, j'aime qu'ils soient flexibles. N'hésitez pas à y ajouter une solution vanille js si vous en avez une.
Vous pouvez utiliser ce composant d'amorçage:
http://jasny.github.io/bootstrap/javascript/#rowlink
Les composants manquants pour votre framework frontal préféré.
<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>
Ajoutez une classe .rowlink
et un attribut data-link="row"
à un élément <table>
or <tbody>
. Pour d'autres options, ajoutez le nom à data-, comme dans data-target="a.mainlink"
Une cellule peut être exclue en ajoutant la .rowlink-skip
classe à la <td>
.
Appelez le masque de saisie via javascript:
$('tbody.rowlink').rowlink()
Il y a un bon moyen de le faire techniquement avec une <a>
balise à l'intérieur <tr>
, qui peut être sémantiquement incorrect (peut vous donner un avertissement de navigateur), mais fonctionnera sans aucun JavaScript/jQuery
requis:
<!-- 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';
}
PS: Notez que l'astuce ici est de mettre la <a>
balise comme dernier élément, sinon elle essaiera de prendre l'espace de la première <td>
cellule.
PPS: Maintenant, votre ligne entière sera cliquable et vous pouvez également utiliser ce lien pour l'ouvrir dans un nouvel onglet (Ctrl / CMD + clic)
<tr>
éléments ne peuvent pas avoir d' <a>
élément en tant qu'enfant. Seuls <td>
et <th>
sont des enfants valides. Voir: stackoverflow.com/questions/12634715/…
Vous pouvez utiliser la méthode javascript onclick dans tr et la rendre cliquable, également si vous devez créer votre lien en raison de certains détails, vous pouvez déclarer une fonction en javascript et l'appeler dans onclick, en passant quelques valeurs.
Voici une façon de placer un élément A transparent sur les lignes du tableau. Les avantages sont:
Désavantages:
Le tableau reste tel quel:
<table id="tab1">
<tbody>
<tr>
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
</tr>
</tbody>
</table>
Ajoutez les liens (pour chaque ligne) via jQuery JavaScript en insérant un élément A dans chaque première colonne et en définissant les propriétés nécessaires:
// 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)
;
});
Le réglage de la largeur et de la hauteur peut être délicat, si de nombreux rembourrages et marges sont utilisés, mais en général, quelques pixels désactivés ne devraient même pas avoir d'importance.
Démonstration en direct ici: http://jsfiddle.net/qo0dx0oo/ (fonctionne dans Firefox, mais pas IE ou Chrome, là le lien est mal positionné)
Correction pour Chrome et IE (fonctionne toujours dans FF aussi): http://jsfiddle.net/qo0dx0oo/2/
onmouseover
Vous pouvez ajouter le rôle de bouton à une ligne de tableau et Bootstrap changera le curseur sans aucune modification CSS. J'ai décidé d'utiliser ce rôle comme un moyen de rendre facilement n'importe quelle ligne cliquable avec très peu de code.
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");
});
});
Vous pouvez appliquer ce même principe pour ajouter le rôle de bouton à n'importe quelle balise.
Ce code ci-dessous rendra votre table entière cliquable. Cliquer sur les liens dans cet exemple affichera le lien dans une boîte de dialogue d'alerte au lieu de suivre le lien.
Le HTML:
Voici le code HTML derrière l'exemple ci-dessus:
<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>
Le CSS
Et le 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;
}
La jQuery
Et enfin le jQuery qui fait que la magie opère:
$(document).ready(function() {
$('#example tr').click(function() {
var href = $(this).find("a").attr("href");
if(href) {
window.location = href;
}
});
});
Ce qu'il fait, c'est quand on clique sur une ligne, une recherche est effectuée pour le href appartenant à une ancre. S'il en trouve un, l'emplacement de la fenêtre est défini sur cette href.
Une option très simple consiste simplement à utiliser le clic, et plus correct, à mon point de vue, car cela sépare la vue et le contrôleur, et vous n'avez pas besoin de coder en dur l'URL ou tout ce que vous devez faire avec le clic . Cela fonctionne également avec Angular ng-click.
<table>
<tr onclick="myFunction(this)">
<td>Click to show rowIndex</td>
</tr>
</table>
<script>
function myFunction(x) {
alert("Row index is: " + x.rowIndex);
}
</script>
Exemple de travail ici
Une autre option utilisant un <a>
, les positions CSS et certains jQuery ou 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;
}
Ensuite, vous devez donner une largeur, en utilisant par exemple jQuery:
$(function () {
var $table = $('table');
$links = $table.find('a.rowLink');
$(window).resize(function () {
$links.width($table.width());
});
$(window).trigger('resize');
});
Je sais que quelqu'un a déjà écrit à peu près la même chose, mais ma façon est la bonne (div ne peut pas être enfant de A) et il est également préférable d'utiliser des classes.
Vous pouvez imiter un tableau en utilisant CSS et faire d'un élément A la ligne
<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 réponse acceptée est excellente, mais je propose une petite alternative si vous ne voulez pas répéter l'url sur chaque tr. Vous mettez donc l'url ou href dans la table data-url et non le 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);
});
});
C'est également bon car vous n'avez pas besoin d'ajouter l'attribut de données de clic à chaque tr non plus. L'autre bonne chose est que nous n'utilisons pas de classe pour déclencher un clic, car les classes ne doivent vraiment être utilisées que pour le style.
Une solution qui n'a pas été mentionnée précédemment consiste à utiliser un seul lien dans une cellule et du CSS pour étendre ce lien sur les cellules:
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>
Bien que la solution principale ici soit excellente, ma solution supprime le besoin de classes. Tout ce que vous devez faire est d'ajouter l'attribut data-href avec l'URL qu'il contient.
J'ai investi beaucoup de temps à essayer de résoudre ce problème.
Il existe 3 approches:
Utilisez JavaScript. Les inconvénients évidents: il n'est pas possible d'ouvrir un nouvel onglet en mode natif, et lorsque vous survolez la ligne, il n'y aura aucune indication sur la barre d'état comme les liens normaux. L'accessibilité est également une question.
Utilisez uniquement HTML / CSS. Cela signifie mettre <a>
imbriqué sous chacun <td>
. Une approche simple comme ce violon ne fonctionne pas - Parce que la surface cliquable n'est pas nécessairement égale pour chaque colonne. Il s'agit d'une grave préoccupation UX. De plus, si vous avez besoin d'un <button>
sur la ligne, ce n'est pas du HTML valide pour l'imbriquer sous la <a>
balise (bien que les navigateurs soient d'accord avec ça).
J'ai trouvé 3 autres façons de mettre en œuvre cette approche. Le premier est ok, les deux autres ne sont pas géniaux.
a) Jetez un œil à cet exemple :
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%;
}
Cela fonctionne, mais en raison des incohérences entre Chrome et Firefox, il nécessite un hack spécifique au navigateur pour surmonter les différences. De plus, Chrome alignera toujours le contenu des cellules vers le haut, ce qui peut entraîner des problèmes avec les longs textes, en particulier si différentes hauteurs de ligne sont impliquées.
b) Réglage <td>
sur{ display: contents; }
. Cela conduit à 2 autres problèmes:
b1. Si quelqu'un d'autre essaie de styliser directement la <td>
balise, comme la définir { width: 20px; }
, nous devons en quelque sorte transmettre ce style à la balise<a>
balise. Nous avons besoin de magie pour cela, probablement plus de magie que dans l'alternative Javascript.
b2. { display: contents; }
est encore expérimental; en particulier, il n'est pas pris en charge sur Edge.
c) Réglage <td>
sur { height: --some-fixed-value; }
. Ce n'est tout simplement pas assez flexible.
La dernière approche, à laquelle je recommande de réfléchir sérieusement, est de ne pas utiliser du tout de lignes cliquables . Les lignes cliquables ne sont pas une excellente expérience UX: il n'est pas facile de les marquer visuellement comme cliquables, et cela pose des défis lorsque plusieurs parties sont cliquables dans les lignes, comme les boutons. Une alternative viable pourrait donc être d'avoir une <a>
balise uniquement sur la première colonne, affichée sous forme de lien régulier, et de lui donner le rôle de parcourir toute la ligne.
Voici une autre façon ...
Le HTML:
<table>
<tbody>
<tr class='clickableRow'>
<td>Blah Blah</td>
<td>1234567</td>
<td>£158,000</td>
</tr>
</tbody>
</table>
La jQuery:
$(function() {
$(".clickableRow").on("click", function() {
location.href="http://google.com";
});
});
Vous pouvez attribuer un identifiant à la ligne, par exemple
<tr id="special"> ... </tr>
puis utilisez jquery pour dire quelque chose comme:
$('#special').onclick(function(){ window="http://urltolinkto.com/x/y/z";})
Pourquoi ne devrions-nous pas utiliser de balises "div" ....
<div>
<a href="" > <div> Table row of content here.. </div> </a>
</div>