How to create collapsible and expandable HTML table columns using the <th> element?

I've searched far and wide for a solution to this conundrum and come up empty-handed. I have a HTML table with a total of 13 columns. The 7th column, labeled Number of Tops, is a sum of columns 8-11: # Short-sleeve, # Long-sleeve, # Sweaters, # Jackets. Each row in the table represents a person's wardrobe. My objective is to have columns 8-11 hidden by default, displaying only columns 1-7 and columns 12 and 13. When the header of the 7th column,

<th>Number of Tops</th>
, is clicked, I want columns 8-11 to expand to reveal detailed information about the breakdown of that total. Additionally, when the columns are expanded, clicking the 7th column's header
<th>Number of Tops</th>
should contract the expanded columns 8-11. It would be ideal to incorporate a smooth CSS transition as the columns expand and collapse, but that's just an added bonus.

Here's the HTML structure of the table I'm referring to:

<div class="table">
  <table>
    <thead>
      <tr>
        <th>Name</th>             <!-- Always visible -->
        <th>Address</th>          <!-- Always visible -->
        <th>Phone Number</th>     <!-- Always visible -->
        <th>Number of Pants</th>  <!-- Always visible -->
        <th>Number of Shoes</th>  <!-- Always visible -->
        <th>Number of Socks</th>  <!-- Always visible -->
        <!-- Column 7: totals column -->
        <th>Number of Tops</th>   <!-- Always visible; clickable -->
        <th># Short-sleeve</th>   <!-- collapsible/expandable -->
        <th># Long-sleeve</th>    <!-- collapsible/expandable -->
        <th># Sweaters</th>       <!-- collapsible/expandable -->
        <th># Jackets</th>        <!-- collapsible/expandable -->
        <th>Number of Hats</th>   <!-- Always visible -->
        <th>Number of Bags</th>   <!-- Always visible -->
      </tr>
    </thead>
    <tbody></tbody>
  </table>
</div>

When the columns are collapsed, I want the corresponding cell values for columns 8-11 to also collapse as if they had a CSS property of display: none. The table should resemble a standard 9-column layout until the 7th column header is clicked, triggering columns 8-11 to elegantly expand from the right side, transforming the table into a 13-column display. Clicking the 7th column header again should smoothly collapse columns 8-11 towards the right side, restoring the original 9-column table layout. The column order should remain unchanged throughout this process.

If feasible, I would like to achieve this effect using only HTML, Javascript, jQuery, and CSS. The table in question is a DataTable.

Thank you for your assistance!

Answer №1

For an easy example, consider using font-size as the property that can be animated. A simple line of JavaScript is required to apply a class to the table itself, enabling other cells in columns 8-11 to also respond to expansion or contraction.

table tr> :nth-child(8),
table tr> :nth-child(9),
table tr> :nth-child(10),
table tr> :nth-child(11) {
  font-size: 0px;
  transition: font-size 1s linear;
}

table.expand tr> :nth-child(8),
table.expand tr> :nth-child(9),
table.expand tr> :nth-child(10),
table.expand tr> :nth-child(11) {
  font-size: 16px;
}
<div class="table">
  <table>
    <thead>
      <tr>
        <th>Name</th>
        <!-- Always visible -->
        <th>Address</th>
        <!-- Always visible -->
        <th>Phone Number</th>
        <!-- Always visible -->
        <th>Number of Pants</th>
        <!-- Always visible -->
        <th>Number of Shoes</th>
        <!-- Always visible -->
        <th>Number of Socks</th>
        <!-- Always visible -->
        <!-- Column 7: totals column -->
        <th onclick="document.querySelector('table').classList.toggle('expand');">Number of Tops</th>
        <!-- Always visible; clickable -->
        <th># Short-sleeve</th>
        <!-- collapsible/expandable -->
        <th># Long-sleeve</th>
        <!-- collapsible/expandable -->
        <th># Sweaters</th>
        <!-- collapsible/expandable -->
        <th># Jackets</th>
        <!-- collapsible/expandable -->
        <th>Number of Hats</th>
        <!-- Always visible -->
        <th>Number of Bags</th>
        <!-- Always visible -->
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Fred</td>
        <!-- Always visible -->
        <td>Seattle</td>
        <!-- Always visible -->
        <td>07777777777</td>
        <!-- Always visible -->
        <td>4</td>
        <!-- Always visible -->
        <td>3</td>
        <!-- Always visible -->
        <td>24</td>
        <!-- Always visible -->
        <!-- Column 7: totals column -->
        <td>18</td>
        <!-- Always visible; -->
        <td>5</td>
        <!-- collapsible/expandable -->
        <td>6</td>
        <!-- collapsible/expandable -->
        <td>4</td>
        <!-- collapsible/expandable -->
        <td>3</th>
          <!-- collapsible/expandable -->
          <th>2</th>
          <!-- Always visible -->
          <th>4</th>
          <!-- Always visible -->
      </tr>
      <tbody>
  </table>
</div>

To add complexity, it might be beneficial to use JavaScript to determine the exact widths of each column and adjust them accordingly for expansion or contraction.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to display a JS alert just one time?

How can I display a message to users on LT IE8 encouraging them to upgrade their browser for a better web experience? I only want the message to appear on their first visit, not every time they refresh the page. Is there a solution for this issue? Thank ...

Tips for utilizing JSON.parse

Within my ajax request, I am encountering the following code: 403: function(jqXHR) { var error = jqXHR.responseText; console.log(error); } When this error occurs, a message is displayed in the console: Htt ...

Customizing Google Maps API v3: Utilizing Custom Images as symbolPath Instead of Default Symbols

Recently, I discovered the fascinating feature called Symbol Animation in Google API's documentation. All aspects of my code are functioning optimally; however, I am curious to know if it is possible to substitute an image for a symbol in the followi ...

Karma is unable to locate the module within the specified relative path

I'm facing a challenge with Karma not being able to load a specific file. As a novice in Karma, I dedicated the entire day to researching and checking documentation for similar issues with no luck. Upon initiating the karma process, it encounters an ...

Error encountered with the $get method of AngularJS Provider during configuration() function

Recently, I configured a Provider that fetches a language JSON file from a web server and delivers it to Angular within the config() method. Here is the provider setup: .provider('language', function () { var languageWsURL , languageC ...

Use the on-screen keyboard to move around by using the arrow keys and choose a value from the list to

I am currently working on developing an on-screen keyboard that allows for navigation using arrow keys and selection with the enter key. My goal is to have each selected key append to an input field. Below is the HTML code I have implemented: <div id ...

Indeed, yet another problem with clearInterval

I could use some assistance as I am currently stuck trying to figure out why the stopTimer() function is not working correctly. Any guidance or suggestions would be highly appreciated. Thank you! http://jsfiddle.net/4Efbd/1/ var counter; function endTim ...

Place the `service` parameter into the `run` function

What are some examples of when to utilize the angular.run method? I have a service that is resource-intensive and takes a significant amount of time to initialize before it can be used in conjunction with my view. angular.module('myApp').service ...

Re-establishing connections in the force-directed graph model

Just getting started with d3.js and I'm currently attempting to reconnect paths between nodes on a force graph. Here is an example image of what I am trying to achieve: https://i.sstatic.net/knvH9.jpg I want to be able to drag the red circle and hav ...

Removing all HTML elements within the div container

My HTML code includes the following: <div class="row" id="conditional-one"> <div class="large-12 columns"> <h3><?php echo $arrayStage_rule_one_title?></h3> <p> <?php echo $arrayS ...

Clever method for enabling image uploads upon image selection without needing to click an upload button using JQuery

Is there a way to automatically upload the file without having to click the upload button? Detail : The code below shows an input field for uploading an image, where you have to select the file and then click the "Upload" button to actually upload it: & ...

Tips for aligning navbar-items vertically in a Bootstrap 5.3 navbar

The navbar is currently transparent, but when scrolling down, it has a white background. However, in the white background, it is not vertically centered. I would greatly appreciate it if you could provide the solution as a URL in CodePen Code: <lin ...

Using Grails to create remote functions with multiple parameters

Currently, I am able to send one parameter to the controller using the code snippet below in Javascript: <g:javascript> var sel = "test"; <g:remoteFunction action="newExisting" method="GET" update="updateThis" params="'sel='+s ...

How to ensure your content is always visible on Mobile Safari iOS 8 by making sure it stays

Although minimal-ui is no longer supported on iOS8, I've encountered an issue with some fixed content at the bottom of a webpage. The page height is set to 100vh to cover the entire viewport, but some of the content at the bottom is extending below t ...

Tips on changing font color within an email body in Outlook using a C#.NET Windows application

While working on a c#.net windows application, I encountered an issue with setting font color for specific lines in the email body when sending mail to Outlook. Despite trying various methods, I was unable to find a solution. Below is a snippet of my code: ...

Eliminate the tiny space between the top of the webpage and the navigation bar

I've made several attempts to eliminate the gap between the navigation and the top by setting margin: 0; and border-box in various places to no avail. Strangely, I couldn't get the navigation bar to stick, so I had to resort to making the header ...

Google Maps integrated AWS server

While utilizing an AWS server for my application, I have encountered a difficulty with Google Maps. When running my application using localhost, Google Maps functions perfectly fine. However, when attempting to run the application using an IP address, it f ...

When an if statement is triggered by an overload of information, it initiates the start of a fresh

I am in need of creating an if statement that will trigger whenever images with IDs 0 to 3 (a total of 4 images) are loaded. This if statement should then generate a new row containing 0 to 3 images, and the same logic needs to be applied for words as well ...

Converting Plain JSON Objects into a Hierarchical Folder Structure using Logic

Looking at the data provided below: [ {name: 'SubFolder1', parent: 'Folder1'}, {name: 'SubFolder2', parent: 'SubFolder1'}, {name: 'SubFolder3', parent: 'SubFolder2'}, {name: 'Document ...

Implementing Pagination in Vue: How to Make it Work with Response Data

I am looking to integrate pagination from the response data into my existing code, while also incorporating filters. JavaScript var entriesList = new Vue({ el: "#post-list-template", data: { posts: [], categories: [], cu ...