Развернуть только выбранную строку во вложенной таблице

#html #jquery #css

#HTML #jquery #css

Вопрос:

Я пытаюсь развернуть вложенную строку в таблице, щелкнув значок. Первоначально я расширялся по щелчку строки, как показано ниже.

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

Все работало нормально. Теперь, когда я хочу развернуть по щелчку, я не знаю, чем заменить ключевое слово «this», чтобы оно расширяло только выбранную строку, а не всю таблицу сразу.

 $(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">j@g.com</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">John@g.com<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">John@g.com
                                    
                                    </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">John@g.com
                                    
                                    </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">John@g.com
                                        
                                    </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;

}
  

Для демонстрации я добавил только одну строку в родительскую таблицу и три в дочернюю таблицу. Как я могу заставить эту функцию расширения работать?

Мы будем признательны за вашу помощь.

Спасибо 🙂

Комментарии:

1. Можете ли вы добавить еще одну строку или 2 в пример, чтобы мы могли видеть, как он структурирован, чтобы мы знали, как выбрать правильную строку?

Ответ №1:

Вам нужно использовать функцию closest для получения tr , а затем перейти к next() классу, который .fold находится в toggleClass('open')

Рабочая демонстрация:

 $(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">j@g.com</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">John@g.com<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">John@g.com

                  </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">John@g.com

                  </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">John@g.com
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </td>
      </tr>

    <tbody>
  </table>
</body>  

Ответ №2:

В ванильном Javascript вы можете использовать следующий ответ: (для jQuery OP, пожалуйста, обратитесь к сообщению @AlwaysHelping)

Я бы сохранил исходный код, добавив предыдущее расширение в качестве глобальной переменной / класса, чтобы закрыть его перед открытием следующего на:

  document.querySelectorAll('tbody.toggle').forEach(e => (e.addEventListener('click', (e) => {
    const current = [e.currentTarget.querySelector('.view'), e.currentTarget.querySelector('.fold')];
    if (window.previous amp;amp; 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;
  })));
  

Если вы решите использовать классы, измените window на правильный this._property

Смотрите следующий фрагмент:

 <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">j@g.com</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">John@g.com<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">John@g.com</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">John@g.com</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">John@g.com</td>
                </tr>
              </tbody>
            </table>
          </div>
        </td>
      </tr>
    </tbody>
    <tbody class="toggle">
      <tr class="view">
        <td col="Name">John 2</td>
        <td col="Designation">j@g.com</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">John@g.com<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">John@g.com</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">John@g.com</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">John@g.com</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 amp;amp; 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>  

Комментарии:

1. Я не совсем понял. Не могли бы вы, пожалуйста, объяснить? Является ли первый подход, предложенный выше, неполным?

2. Я обновил сообщение в надежде, что оно не требует пояснений, если нет, просто дайте мне знать

3. @aemonge Почему вы предлагаете 15 других строк кода, чтобы сделать то же самое и усложнить задачу, чтобы получить те же результаты. Когда простая аккуратная функция closest может выполнить эту работу. Смотрите мой ответ.

4. @aemonge используйте DRY метод, который означает do not repeat yourself при написании кода соответствие стандарту кодирования.

5. @AlwaysHelping Я стремлюсь помочь, имея только одну строку «открытой», что, как я думал, было проблемой. Как вы говорите, это можно сделать более эффективно с .closest , хотя раньше я избегал боковой навигации в DOM.