HTML entire table row as checkbox label

Viewed 156

I'm working on a table and I am trying to make it so if you click anywhere on a row, including blank spaces, then the corresponding checkbox will be selected. I tried putting a <label> before/after the <tr> tag, but that did not seem to work at all. Next, I tried making the contents of each <td> as a label, which works fine, except if you click the blank space on the row between the text then nothing happens.

How can I make the entire row selectable?

body {margin: 0; background-color: #F2F2F2;}

.topbar {
  z-index: 10;
  position: fixed;
  top: 0; left: 0;
  width: 100vw; height: 56px;
  font-size: x-large;
  background-color: #5B7042;
  border-bottom: 4px solid #3F5328}

#bottombar {
  position: fixed;
  width: 100vw; height: 60px;
  bottom: 0; left: 0;
  padding: 4px;
  box-sizing: border-box;
  border-top: 2px solid darkgray;
  background-color: white;}


#list {
  padding: 20px;
  margin-top: 60px;
  margin-bottom: 60px;
  min-height: calc(100vh - 120px);
}

table {border-spacing: 0}

th{
  padding: 16px;
  color: #5B7042;
  border-bottom: 2px solid #5B7042}

td {
  padding-top: 6px;
  padding-bottom: 6px;
  border-bottom: 1px solid lightgray;}

td:not(.name) {text-align: center}

tbody tr:hover{
  transform: scale(1.01);
  background-color: #E3E3E3}

.pic{
  display: inline-block;
  width: 25px;
  clip-path: circle();
  margin-right: 10px;}
<link rel='stylesheet' href='https://classcolonies.com/resources/style.css'>

<div class='topbar'></div>

<form id='list'>
  <table>
    <colgroup>
      <col width='1%'>
      <col width='6%'>
      <col width='3%'>
      <col width='3%'>
      <col width='3%'>
      <col width='3%'>
      <col width='3%'>
    </colgroup>
    <thead>
      <tr>
        <th><input type='checkbox'></th>
        <th>Student</th>
        <th>Seen</th>
        <th>Lvl</th>
        <th>Pay</th>
        <th>Money</th>
        <th>Streak</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td><input type='checkbox' id='1'></td>
        <td class='name'>
          <label for="1">
            <img class='pic' src='https://mrdansby.com/resources/pics/1.png'>
            <span>John Doe</span>
          </label>
        </td>
        <td><label for="1">1d ago</label></td>
        <td><label for="1">15</label></td>
        <td><label for="1">$10/hr</label></td>
        <td><label for="1">$1300</label></td>
        <td><label for="1">32</label></td>
      </tr>
      <tr>
        <td><input type='checkbox' id='2'></td>
        <td class='name'>
          <label for="2">
            <img class='pic' src='https://mrdansby.com/resources/pics/1.png'>
            <span>Jane Doe</span>
          </label>
        </td>
        <td><label for="2">3m ago</label></td>
        <td><label for="2">21</label></td>
        <td><label for="2">$11/hr</label></td>
        <td><label for="2">$2560</label></td>
        <td><label for="2">15</label></td>
      </tr>
    </tbody>
  </table>
</form>

<div id='bottombar'></div>

2 Answers

It's not possible to use the <label> tag to turn the entire table row into a label. To do this, you need to use JavaScript.

In the code below, a click event is attached to the <tr> elements of a table. If one of them is clicked, the checkbox inside it is toggled. That happens even if you click the spaces between cells.

Also, note that every checkbox has an aria-labelledBy attribute which points to the user name table cell, preserving accessibility. You can apply the same concepts to your table.

document.querySelector('table').addEventListener('click', (e) => {
    if (e.target.tagName === 'INPUT') return;
    const row = e.target.tagName === 'TR' ? e.target : e.target.parentNode;
    const childCheckbox = row.querySelector('input[type="checkbox"]');
    childCheckbox.checked = !childCheckbox.checked;
});
td {
  padding: 1rem;
  border: 1px solid black;
}
<table>
  <tr>
    <td>
      <input type="checkbox" aria-labelledBy="user1">
    </td>
    <td id="user1">User 1</td>
    <td>Info A</td>
    <td>Info B</td>
  </tr>
  <tr>
    <td>
      <input type="checkbox" aria-labelledBy="user2">
    </td>
    <td id="user2">User 2</td>
    <td>Info A</td>
    <td>Info B</td>
  </tr>
<table>

The way I was able to get this working was I added a class name to the tr tags and then used some JavaScript. The JavaScript I'm using added the click event listener to the entire row and then from within the click even listener I checked to see if the checkbox was checked. I created a CodeSandbox for this: https://codesandbox.io/s/trusting-architecture-8s13o?file=/src/index.js

Related