HarshVardhan Bandta
HarshVardhan Bandta

Reputation: 139

Expand only the selected row in a nested table

I am trying to expand a nested row in a table by clicking an icon. Initially, I was expanding on click of the row as below.

$(function(){
    $(".fold-table tr.view").on("click", function(){
      $(this).toggleClass("open").next(".fold").toggleClass("open");
    });
  });

It was working fine. Now when I want to expand on click I don't know what to replace the 'this' keyword with so the it only expands the selected row and not the entire table at once.

$(function(){
  $(".expand").on("click", function(){
    $(this).toggleClass("open").next(".fold").toggleClass("open");
  });
})
<body>

    <table class="table fold-table parent" id="table">
        <thead>
            <tr>

                <th scope="col">Name</th>
                <th scope="col">Designation</th>
                <th scope="col">Contact Details</th>
                <th scope="col">Email</th>
            </tr>
        </thead>
        <tbody>
            <tr class="view">

                <td col="Name">John</td>
                <td col="Designation">[email protected]</td>
                <td col="Contact Details">
                    <span class="contactInfo">
                        <img class="contact mr-2" src="./assets/call.png" />35373726<br>
                        <img class="contact mr-2" src="./assets/call.png" />35373726
                    </span>
                </td>
                <td col="Email">[email protected]<img class="expand ml-2" src="arrow.png" /></td>
            </tr>
            <tr class="fold">
                <td colspan="4">
                    <div class="fold-content">

                        <table class="child">

                            <tbody>
                                <tr>
                                    <td col="Name">SUB Category 1</td>
                                    <td col="Designation">SUB Category 2</td>
                                    <td col="Contact Details">SUB Category 3</td>
                                    <td col="Email">[email protected]
                                    
                                    </td>
                                </tr>

                                <tr>

                                    <td col="Name">SUB Category 1</td>
                                    <td col="Designation">SUB Category 2</td>
                                    <td col="Contact Details">SUB Category 3</td>
                                    <td col="Email">[email protected]
                                    
                                    </td>
                                </tr>
                                <tr>
                                    <td col="Name">SUB Category 1</td>
                                    <td col="Designation">SUB Category 2</td>
                                    <td col="Contact Details">SUB Category 3</td>
                                    <td col="Email">[email protected]
                                        
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </td>
            </tr>

        <tbody>
    </table>
</body>
.expand {
  cursor: pointer;
}

 table.fold-table > tbody > tr.fold {
  display: none;
}

table.fold-table > tbody > tr.fold.open {
  display: table-row;

}

For demonstration, I have only added one row in parent table and three in child table. How can I get this expand thing to work ?

Your help will be appreciated.

Thanks :)

Upvotes: 1

Views: 1140

Answers (2)

aemonge
aemonge

Reputation: 2347

In vanilla Javascript you can use the following answer: (for the jQuery OP please refer to @AlwaysHelping post)

I would keep the original code, adding the previous expand as a global/class variable to close it before opening the next on:

 document.querySelectorAll('tbody.toggle').forEach(e => (e.addEventListener('click', (e) => {
    const current = [e.currentTarget.querySelector('.view'), e.currentTarget.querySelector('.fold')];
    if (window.previous && window.previous[0] !== current[0]) {
      window.previous[0].classList.remove('open');
      window.previous[1].classList.remove('open');
    }

    current[0].classList.toggle('open');
    current[1].classList.toggle('open');
    window.previous = current;
  })));

If you decide to use clases change the window into the correct this._property

See the following snippet:

<style>
  .fold {
    visibility: hidden;
  }
  .fold.open {
    visibility: visible;
  }
</style>

<body>
  <table class="table fold-table parent" id="table">
    <thead>
      <tr>
        <th scope="col">Name</th>
        <th scope="col">Designation</th>
        <th scope="col">Contact Details</th>
        <th scope="col">Email</th>
      </tr>
    </thead>
    <tbody class="toggle">
      <tr class="view">
        <td col="Name">John</td>
        <td col="Designation">[email protected]</td>
        <td col="Contact Details">
          <span class="contactInfo">
            <img class="contact mr-2" src="./assets/call.png" />35373726<br />
            <img class="contact mr-2" src="./assets/call.png" />35373726
          </span>
        </td>
        <td col="Email">[email protected]<img class="expand ml-2" src="arrow.png" /></td>
      </tr>
      <tr class="fold">
        <td colspan="4">
          <div class="fold-content">
            <table class="child">
              <tbody>
                <tr>
                  <td col="Name">SUB Category 1</td>
                  <td col="Designation">SUB Category 2</td>
                  <td col="Contact Details">SUB Category 3</td>
                  <td col="Email">[email protected]</td>
                </tr>
                <tr>
                  <td col="Name">SUB Category 1</td>
                  <td col="Designation">SUB Category 2</td>
                  <td col="Contact Details">SUB Category 3</td>
                  <td col="Email">[email protected]</td>
                </tr>
                <tr>
                  <td col="Name">SUB Category 1</td>
                  <td col="Designation">SUB Category 2</td>
                  <td col="Contact Details">SUB Category 3</td>
                  <td col="Email">[email protected]</td>
                </tr>
              </tbody>
            </table>
          </div>
        </td>
      </tr>
    </tbody>
    <tbody class="toggle">
      <tr class="view">
        <td col="Name">John 2</td>
        <td col="Designation">[email protected]</td>
        <td col="Contact Details">
          <span class="contactInfo">
            <img class="contact mr-2" src="./assets/call.png" />35373726<br />
            <img class="contact mr-2" src="./assets/call.png" />35373726
          </span>
        </td>
        <td col="Email">[email protected]<img class="expand ml-2" src="arrow.png" /></td>
      </tr>
      <tr class="fold">
        <td colspan="4">
          <div class="fold-content">
            <table class="child">
              <tbody>
                <tr>
                  <td col="Name">SUB Category 1</td>
                  <td col="Designation">SUB Category 2</td>
                  <td col="Contact Details">SUB Category 3</td>
                  <td col="Email">[email protected]</td>
                </tr>
                <tr>
                  <td col="Name">SUB Category 1</td>
                  <td col="Designation">SUB Category 2</td>
                  <td col="Contact Details">SUB Category 3</td>
                  <td col="Email">[email protected]</td>
                </tr>
                <tr>
                  <td col="Name">SUB Category 1</td>
                  <td col="Designation">SUB Category 2</td>
                  <td col="Contact Details">SUB Category 3</td>
                  <td col="Email">[email protected]</td>
                </tr>
              </tbody>
            </table>
          </div>
        </td>
      </tr>
    </tbody>
  </table>
</body>

<script>
  document.querySelectorAll('tbody.toggle').forEach(e => (e.addEventListener('click', (e) => {
    const current = [e.currentTarget.querySelector('.view'), e.currentTarget.querySelector('.fold')];
    if (window.previous && window.previous[0] !== current[0]) {
      window.previous[0].classList.remove('open');
      window.previous[1].classList.remove('open');
    }

    current[0].classList.toggle('open');
    current[1].classList.toggle('open');
    window.previous = current;
  })));
</script>

Upvotes: 1

Always Helping
Always Helping

Reputation: 14570

You need to use closest function to get tr and then go to next() class which is .fold to toggleClass('open')

Working Demo:

$(function(){
  $(".expand").on("click", function(){
    $(this).toggleClass("open").closest('tr').next('.fold').toggleClass("open");
  });
})
.expand {
  cursor: pointer;
}

 table.fold-table > tbody > tr.fold {
  display: none;
}

table.fold-table > tbody > tr.fold.open {
  display: table-row;

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>

  <table class="table fold-table parent" id="table">
    <thead>
      <tr>

        <th scope="col">Name</th>
        <th scope="col">Designation</th>
        <th scope="col">Contact Details</th>
        <th scope="col">Email</th>
      </tr>
    </thead>
    <tbody>
      <tr class="view">

        <td col="Name">John</td>
        <td col="Designation">[email protected]</td>
        <td col="Contact Details">
          <span class="contactInfo">
            <img class="contact mr-2" src="./assets/call.png" />35373726<br>
            <img class="contact mr-2" src="./assets/call.png" />35373726
          </span>
        </td>
        <td col="Email">[email protected]<img class="expand ml-2" src="arrow.png" /></td>
      </tr>
      <tr class="fold">
        <td colspan="4">
          <div class="fold-content">
            <table class="child">

              <tbody>
                <tr>
                  <td col="Name">SUB Category 1</td>
                  <td col="Designation">SUB Category 2</td>
                  <td col="Contact Details">SUB Category 3</td>
                  <td col="Email">[email protected]

                  </td>
                </tr>

                <tr>

                  <td col="Name">SUB Category 1</td>
                  <td col="Designation">SUB Category 2</td>
                  <td col="Contact Details">SUB Category 3</td>
                  <td col="Email">[email protected]

                  </td>
                </tr>
                <tr>
                  <td col="Name">SUB Category 1</td>
                  <td col="Designation">SUB Category 2</td>
                  <td col="Contact Details">SUB Category 3</td>
                  <td col="Email">[email protected]
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </td>
      </tr>

    <tbody>
  </table>
</body>

Upvotes: 1

Related Questions