Home > Mobile >  Collapsible rows in table without using any IDs
Collapsible rows in table without using any IDs

Time:04-29

I have created a table in which whenever a user clicks the row it expands its next hidden row. to do that I have used the below script in which the next element of the class row-details is targeted as a hidden element. The issue here is to use an id or class to target each div inside the row.

If I use normal div elements then the script can use this.nextElementSibling; to identify the next div element which can be hidden and when the first div is clicked it will expand.

var tableRow = document.getElementsByClassName('row');

for (var i = 0; i < tableRow.length; i  ) {
    tableRow[i].addEventListener('click', function () {
        var tableContent = document.querySelector('.row-details');
        if (tableContent.style.maxHeight) {
            tableContent.style.maxHeight = null;
        } else {
            tableContent.style.maxHeight = tableContent.scrollHeight   'px';
        }
    });
}

In the below code there are 2 rows each with a hidden row containing details. I have used the same class for both hidden rows. What I am trying to achieve is to expand the hidden row without defining any Id or class. min-height property is not working on tr tags.

var tableRow = document.getElementsByClassName('row');

for (var i = 0; i < tableRow.length; i  ) {
    tableRow[i].addEventListener('click', function () {
        var tableContent = this.nextElementSibling;
        if (tableContent.style.maxHeight) {
            tableContent.style.maxHeight = null;
        } else {
            tableContent.style.maxHeight = tableContent.scrollHeight   'px';
        }
    });
}
.row-details{
  max-height: 0;
  overflow: hidden;
  transition: all 300ms ease;
}

table {
  border-collapse: unset;
}
<table>
  <tr>
    <th>Date</th>
    <th>Data-1</th>
    <th>Data-2</th>
  </tr>
  <tr >
    <td>Lorem</td>
    <td>ipsum</td>
    <td>dolor sit amet.</td>
  </tr>
  <tr>
    <td colspan="3">
      <div >
        <span>Lorem, ipsum.</span>
      </div>
    </td>
  </tr>
  <tr >
    <td>Lorem</td>
    <td>ipsum</td>
    <td>dolor sit amet.</td>
  </tr>
  <tr>
    <td colspan="3">
      <div >
        <span>Lorem, ipsum.</span>
      </div>
    </td>
  </tr>
</table>

Changed Code:

const table = document.querySelector('table');

    table.addEventListener('click', (e) => {
        let header_row = e.target.closest('tr.row');
        let details_row = header_row.nextElementSibling;
        details_row.classList.add('show');

        var tableContent = document.querySelector('tr.show .row-details');

        if (tableContent.style.maxHeight) {
            tableContent.style.maxHeight = null;
            details_row.classList.remove('show');
        } else {
            tableContent.style.maxHeight = tableContent.scrollHeight   'px';
        }
    });
.row-details {
  max-height: 0;
  overflow: hidden;
  transition: all 300ms ease;
}


table {
  border-collapse: unset;
}

tr.row {
  cursor: pointer;
}
<table>
  <tr>
    <th>Date</th>
    <th>Data-1</th>
    <th>Data-2</th>
  </tr>
  <tr >
    <td>Lorem</td>
    <td>ipsum</td>
    <td>dolor sit amet.</td>
  </tr>
  <tr>
    <td colspan="3">
      <div >
        <span>Lorem, ipsum.</span>
      </div>
    </td>
  </tr>
  <tr >
    <td>Lorem</td>
    <td>ipsum</td>
    <td>dolor sit amet.</td>
  </tr>
  <tr>
    <td colspan="3">
      <div >
        <span>Lorem, ipsum.</span>
      </div>
    </td>
  </tr>
</table>

CodePudding user response:

Here I just have one event listener for the entire table. When clicked, I find the closest tr.row and toggle a class name on the nextElementSibling. With a selector I can then control the <div>.

If you are using the max-height technique you can just put a max-height that is larger then the content.

const table = document.querySelector('table');

table.addEventListener('click', e => {
  let header_row = e.target.closest('tr.row');
  let details_row = header_row.nextElementSibling;
  details_row.classList.toggle('show');
});
.row-details {
  max-height: 0;
  overflow: hidden;
  transition: all 300ms ease;
}

tr.show .row-details {
  max-height: 3em;
}

table {
  border-collapse: unset;
}

tr.row {
  cursor: pointer;
}
<table>
  <tr>
    <th>Date</th>
    <th>Data-1</th>
    <th>Data-2</th>
  </tr>
  <tr >
    <td>Lorem</td>
    <td>ipsum</td>
    <td>dolor sit amet.</td>
  </tr>
  <tr>
    <td colspan="3">
      <div >
        <span>Lorem, ipsum.</span>
      </div>
    </td>
  </tr>
  <tr >
    <td>Lorem</td>
    <td>ipsum</td>
    <td>dolor sit amet.</td>
  </tr>
  <tr>
    <td colspan="3">
      <div >
        <span>Lorem, ipsum.</span>
      </div>
    </td>
  </tr>
</table>

  • Related