'Creating a HTML table with expandable/collapsible sections

I created an HTML table, and each row has its own section that expands and collapses when clicking on that row, thanks to some jQuery. I got it mostly set up, but there are two things:

  1. When collapsed (which should happen by default), there's a sliver of that hidden section still showing. And when I click on it, it collapses itself and no longer expands until I reload the page.
  2. I would love any advice on how to make only one row expand its hidden section at a time. So if there's a row that's expanded and I go to click on another row, it'll collapse the previous row that was expanded.

I would appreciate any help! I'm still very new at this.

DEMO HERE

function myFunction() {
  // Declare variables
  var input, filter, table, tr, td, i, txtValue;
  input = document.getElementById("search");
  filter = input.value.toUpperCase();
  table = document.getElementById("myTable");
  tr = table.getElementsByTagName("tr");

  // Loop through all table rows, and hide those who don't match the search query
  for (i = 0; i < tr.length; i++) {
    td = tr[i].getElementsByTagName("td")[0];
    if (td) {
      txtValue = td.textContent || td.innerText;
      if (txtValue.toUpperCase().indexOf(filter) > -1) {
        tr[i].style.display = "";
      } else {
        tr[i].style.display = "none";
      }
    }
  }
}

$(function() {
    $("td[colspan=3]").find("p").hide();
    $("table").click(function(event) {
        event.stopPropagation();
        var $target = $(event.target);
        if ( $target.closest("td").attr("colspan") > 1 ) {
            $target.slideUp();
        } else {
            $target.closest("tr").next().find("p").slideToggle();
        }                    
    });
});
#search {
  width: 50%;
  font-size: 16px;
  padding: 7px;
  border: 1px solid #ddd;
  margin-bottom: 15px;
}

#myTable {
  border-collapse: collapse;
  width: 100%;
  border: 1px solid #ddd;
  font-size: 14px;
}

#myTable th, #myTable td {
  text-align: left; /* Left-align text */
  padding: 12px; /* Add padding */
}

#myTable tr {
  /* Add a bottom border to all table rows */
  border-bottom: 1px solid #ddd;
}

#myTable tr.header, #myTable tr:hover {
  /* Add a grey background color to the table header and on hover */
  background-color: #f1f1f1;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="stylesheet.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="javascript.js"></script>
<title>My Experimental Database</title>
</head>

<body>

<input type="text" id="search" onkeyup="myFunction()" placeholder="Search for names..">

<table id="myTable">
  <tr class="header">
    <th>Name</th>
    <th>Grade</th>
    <th>School</th>
  </tr>
  <tr>
    <td>Dave Newman</td>
    <td>Freshman</td>
    <td>Bolder HS</td>
  </tr>
  <tr>
    <td colspan="3" id="info"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut imperdiet tellus et libero convallis, posuere auctor odio ultrices. Suspendisse aliquet iaculis ligula sit amet condimentum. Nullam quis sollicitudin sem, a fermentum ex. Cras vel consequat nisl. Fusce vulputate dui sit amet lorem gravida scelerisque. Proin molestie in erat ut commodo. In ut quam lorem. Quisque eu feugiat orci. Donec nulla elit, feugiat sed pulvinar id, aliquet ac tortor. Morbi ornare consequat justo, id fermentum odio convallis consectetur. Curabitur ac neque rutrum, ultricies sapien at, fermentum nisl. Aenean in gravida nulla, quis placerat est. Nunc orci ipsum, pharetra eget ullamcorper id, venenatis ac quam. Quisque a commodo erat. Etiam et orci ullamcorper, volutpat sapien vitae, porttitor lectus.</p>
    </td>
  </tr>
  <tr>
    <td>Garret Miller</td>
    <td>Senior</td>
    <td>Field HS</td>
  </tr>
  <tr>
    <td colspan="3" id="info"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut imperdiet tellus et libero convallis, posuere auctor odio ultrices. Suspendisse aliquet iaculis ligula sit amet condimentum. Nullam quis sollicitudin sem, a fermentum ex. Cras vel consequat nisl. Fusce vulputate dui sit amet lorem gravida scelerisque. Proin molestie in erat ut commodo. In ut quam lorem. Quisque eu feugiat orci. Donec nulla elit, feugiat sed pulvinar id, aliquet ac tortor. Morbi ornare consequat justo, id fermentum odio convallis consectetur. Curabitur ac neque rutrum, ultricies sapien at, fermentum nisl. Aenean in gravida nulla, quis placerat est. Nunc orci ipsum, pharetra eget ullamcorper id, venenatis ac quam. Quisque a commodo erat. Etiam et orci ullamcorper, volutpat sapien vitae, porttitor lectus.</p>
    </td>
  </tr>
  <tr>
    <td>Diana Feldman</td>
    <td>Junior</td>
    <td>Field HS</td>
  </tr>
  <tr>
    <td colspan="3" id="info"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut imperdiet tellus et libero convallis, posuere auctor odio ultrices. Suspendisse aliquet iaculis ligula sit amet condimentum. Nullam quis sollicitudin sem, a fermentum ex. Cras vel consequat nisl. Fusce vulputate dui sit amet lorem gravida scelerisque. Proin molestie in erat ut commodo. In ut quam lorem. Quisque eu feugiat orci. Donec nulla elit, feugiat sed pulvinar id, aliquet ac tortor. Morbi ornare consequat justo, id fermentum odio convallis consectetur. Curabitur ac neque rutrum, ultricies sapien at, fermentum nisl. Aenean in gravida nulla, quis placerat est. Nunc orci ipsum, pharetra eget ullamcorper id, venenatis ac quam. Quisque a commodo erat. Etiam et orci ullamcorper, volutpat sapien vitae, porttitor lectus.</p>
    </td>
  </tr>
</table>

</body>
</html>


Solution 1:[1]

What remains visible of those rows, is caused by the padding you have defined on td cells.

One solution is to move this padding into the p elements, so that the jQuery sliding animation will also apply to that padding.

For that to happen, add this CSS:

#myTable td[colspan] {
  padding-top: 0; padding-bottom: 0;
} 

#myTable td[colspan] p {
  padding-top: 12px; padding-bottom: 12px;
} 

For the second question: to only allow at most one section to be expanded, close all paragraphs that are different from the targeted one. So let the else block be like this:

    var $p = $target.closest("tr").next().find("p");
    $p.slideToggle();
    $("td[colspan] p").not($p).slideUp();

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1