web-dev-qa-db-fra.com

comment faire une ligne entière dans un tableau cliquable en tant que lien?

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>
339
user1038814

Vous utilisez Bootstrap, ce qui signifie que vous utilisez jQuery: ^). Une façon de le faire est donc:

<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 switch, vous pouvez faire ce que vous voulez dans la fonction de gestion des clics. Lisez sur jQuery et comment écrire des gestionnaires. 

L’avantage d’utiliser un class over 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 se chargerait de toutes les lignes.

Une autre option

Vous pouvez utiliser les rappels Bootstrap jQuery comme ceci (dans un rappel document.ready):

$("#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 de la table (ce qui se produit avec l'autre option).


Remarque

Puisque ceci a été posté, window.document.location est obsolète (ou au moins obsolète), utilisez plutôt window.location.

496
Ahmed Masud

Tu ne peux pas faire ça. C'est HTML invalide. Vous ne pouvez pas mettre un <a> entre un <tbody> et un <tr>. Essayez ceci à la place:

<tr onclick="window.location='#';">
   ...
</tr>

Lorsque vous y travaillerez, vous voudrez utiliser JavaScript pour affecter le gestionnaire de clics en dehors du code HTML.

178
davidfurber

Vous pouvez inclure une ancre dans 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; 
}

Exemple jsFiddle ici.

C’est probablement aussi optimal que possible, à moins de recourir à JavaScript.

144
lifetimes

Oui, mais pas avec les éléments <table> standard. Si vous utilisez les propriétés de style display: table, vous le pouvez. Ici et ici 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 class="table">
  <div class="row">
    <div class="cell">
      1.1
    </div>
    <div class="cell">
      1.2
    </div>
    <div class="cell">
      1.3
    </div>
  </div>

  <a class="row" href="#">
    <div class="cell">
      2.1
    </div>
    <div class="cell">
      2.2
    </div>
    <div class="cell">
      2.3
    </div>
  </a>
</div>

Notez que les rôles aria sont utilisés pour garantir une accessibilité correcte, car les éléments <table> standard ne sont pas utilisés. Vous devrez peut-être ajouter des rôles supplémentaires tels que role="columnheader", le cas échéant. En savoir plus au guide suivant ici .

75
Trevin Avery

Une solution beaucoup plus flexible consiste à cibler n'importe quoi avec l'attribut data-href. C'était que vous pouvez réutiliser le code facilement dans 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 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 vos 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 de ce genre, je les aime flexibles. N'hésitez pas à ajouter une solution Vanilla js à celle-ci si vous en avez une. 

8
AbdelElrafa

Vous pouvez utiliser ce composant d'amorçage:

http://jasny.github.io/bootstrap/javascript/#rowlink

Jasny Bootstrap

Les composants manquants pour votre infrastructure frontale préférée.

<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>

Usage

Via des attributs de données

Ajoutez la classe .rowlink et attribuez data-link="row" à un élément <table> ou <tbody>. Pour d'autres options, ajoutez le nom à data-, comme dans data-target="a.mainlink". Une cellule peut être exclue en ajoutant la classe .rowlink-skip à <td>.

Via JavaScript

Appelez le masque de saisie via javascript:

$('tbody.rowlink').rowlink()
6
phlegx

Vous pouvez utiliser la méthode javascript de onclick dans tr et la rendre cliquable. Aussi, 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 lui transmettant certaines valeurs.

5
Anahit Serobyan

Il existe un bon moyen de le faire techniquement avec la balise <a> à l'intérieur de <tr>, qui peut être sémantiquement incorrecte (peut vous donner un avertissement pour le navigateur), mais fonctionnera sans que JavaScript/jQuery soit 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: Remarquez que l’astuce consiste ici à placer le tag <a> en dernier élément, sinon il essaiera de prendre l’espace de la première cellule <td>.

PPS: Toute votre ligne sera maintenant cliquable et vous pourrez aussi utiliser ce lien pour ouvrir un nouvel onglet (Ctrl/CMD + clic)

5
Ronen

Voici un moyen de placer un élément A transparent sur les lignes du tableau. Les avantages sont:

  • est un élément de lien réel: lors du survol du pointeur, affiche le lien cible dans la barre d'état, peut être consulté au clavier, peut être ouvert dans un nouvel onglet ou une nouvelle fenêtre, l'URL peut être copiée, etc.
  • la table a la même apparence que si le lien n'était pas ajouté
  • aucun changement dans le code de la table elle-même

Désavantages:

  • la taille de l'élément A doit être définie dans un script, à la fois lors de la création et après toute modification de la taille de la ligne qu'il recouvre (sinon, cela pourrait se faire sans JavaScript, ce qui est toujours possible si la taille de la table est également définie en HTML ou CSS)

La table reste telle quelle:

<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 JavaScript jQuery 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 marges et marges sont utilisés, mais en règle générale, une réduction de quelques pixels ne devrait pas être prise en compte.

Démo en direct ici: http://jsfiddle.net/qo0dx0oo/ (fonctionne dans Firefox, mais pas IE ou Chrome, le lien est mal positionné)

Corrigé pour Chrome et IE (fonctionne toujours aussi en FF): http://jsfiddle.net/qo0dx0oo/2/

4
David Balažic

Je sais que quelqu'un a déjà écrit à peu près la même chose, mais mon chemin est le bon (div ne peut pas être l'enfant de A) et il vaut mieux utiliser des classes.

Vous pouvez imiter une table en utilisant CSS et en faire 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;}
3
Sidupac

Une autre option utilisant un <a>, des positions CSS et quelques 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');
    });
3
Yisela

Ce code ci-dessous rendra votre table entière cliquable. Cliquez sur les liens dans cet exemple pour afficher 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>&nbsp;</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;
}

Le jQuery

Et enfin le jQuery qui rend la magie opérée:

    $(document).ready(function() {

    $('#example tr').click(function() {
        var href = $(this).find("a").attr("href");
        if(href) {
            window.location = href;
        }
    });

});

Lorsque vous cliquez sur une ligne, une recherche est effectuée sur le href appartenant à une ancre. S'il en trouve un, l'emplacement de la fenêtre est défini sur href.

3
Aydan Aleydin

Vous pouvez ajouter le rôle de bouton à une ligne de la table et Bootstrap modifiera le curseur sans aucune modification CSS. J'ai décidé d'utiliser ce rôle pour rendre facilement une 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.

2
Todd Skelton

je préférerais utiliser onclick="" attribut car il est facile à utiliser et à comprendre pour les débutants comme

 <tr onclick="window.location='any-page.php'">
    <td>UserName</td>
    <td>Email</td>
    <td>Address</td>
</tr>
2
Ali Raza

La réponse acceptée est excellente, mais je propose une petite alternative si vous ne voulez pas répéter l’URL sur tous les tr . Vous mettez donc l’URL ou href dans le tableau 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);
    });
});

Cela est également utile car vous n'avez pas besoin d'ajouter l'attribut de données de clic à chaque transaction. L'autre avantage est que nous n'utilisons pas de classe pour déclencher un clic, car les classes ne devraient être utilisées que pour le style.

1
Thomas Williams

Une option très simple (fonctionne aussi 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

1
Wendell Pereira

Obtenu en utilisant la norme Bootstrap 4.3+ comme suit - aucun jQuery ni aucune classe css supplémentaire n'est nécessaire!

La clé consiste à utiliser stretched-link sur le texte de la cellule et à définir <tr> en tant que 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 sur aucune valeur (comme dans l'exemple ci-dessus).

Pour plus d'informations, lisez le documentation Bootstrap pour stretched-link.

0
Krishna Gupta

Voici un autre moyen ...

Le HTML:

<table>
<tbody>
       <tr class='clickableRow'>
       <td>Blah Blah</td>
       <td>1234567</td>
       <td>£158,000</td>
        </tr>
</tbody>
</table>

Le jQuery:

$(function() {
      $(".clickableRow").on("click", function() {
          location.href="http://google.com";

      });

});
0
klewis

J'ai passé beaucoup de temps à essayer de résoudre ce problème avec HTML uniquement. Signification mettre <a> imbriqué sous chaque <td>. Pas encore de succès.

Le principal problème de cette approche est que la hauteur <a> peut être différente pour chaque colonne. Vous pouvez voir cela dans le violon proposé par @midstack un peu plus tôt dans cette page. Ainsi, la surface cliquable n'est pas nécessairement égale pour chaque colonne. Ceci est une préoccupation sérieuse UX.

J'ai trouvé 2 façons de résoudre ce problème, aucune n'est idéale.

a) Régler <td> sur { display: contents; }. Cela conduit à 2 autres problèmes:

  1. Si quelqu'un d'autre essaie de styler directement la balise <td>, comme pour la définir sur { width: 20px; }, nous devons passer ce style à la balise <a>. Nous avons besoin de magie pour le faire, probablement plus que dans l’alternative Javascript.

  2. { display: contents; } est toujours expérimental; Plus précisément, il n'est pas pris en charge sur Edge.

b) Régler <td> sur { height: --some-fixed-value; }. Ce n'est tout simplement pas assez souple.

0
gamliela
<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 cours. Tout ce que vous avez à faire est d’ajouter l’attribut data-href avec l’URL qu’il contient.

0

Vous pouvez donner à la ligne un identifiant, par exemple.

<tr id="special"> ... </tr>

puis utilisez jquery pour dire quelque chose comme:

$('#special').onclick(function(){ window="http://urltolinkto.com/x/y/z";})

0
Peter Berg