Расширение и сворачивание строки таблицы (tr) с помощью jquery

enter image description here

У меня есть таблица с активными и неактивными элементами. Эта таблица динамически заполняется из базы данных. Я пытаюсь добавить переключатель только для неактивных элементов в своей таблице и отобразить все активные элементы. Я имею в виду, что хочу показать все активные элементы и переключить только неактивные элементы в моей таблице.

<div class="alertsList">
    <table width="100%">
        <tbody>
            <tr>
                <th></th>
                <th>Id</th>
                <th>From</th>
                <th>Action</th>
                <th>State</th>
                <th>time</th>
                <tr class="alertRow">
                    <td></td>
                    <td>1025973</td>
                    <td>SYSTEM</td>
                    <td>false</td>
                    <td class="Active">Active</td>
                    <td>2014-09-23T00:59:26.92</td>
                </tr>
                <tr class="alertRow">
                    <td></td>
                    <td>1025974</td>
                    <td>SYSTEM</td>
                    <td>false</td>
                    <td class="Active">Active</td>
                    <td>2014-09-23T00:59:26.92</td>
                </tr>
                <tr class="alertRow">
                    <td></td>
                    <td>1025974</td>
                    <td>SYSTEM</td>
                    <td>false</td>
                    <td class="InActive">InActive</td>
                    <td>2014-09-23T00:59:26.92</td>
                </tr>
                <tr class="alertRow">
                    <td></td>
                    <td>1025974</td>
                    <td>SYSTEM</td>
                    <td>false</td>
                    <td class="InActive">InActive</td>
                    <td>2014-09-23T00:59:26.92</td>
                </tr>
                <tr class="alertRow">
                    <td></td>
                    <td>1025974</td>
                    <td>SYSTEM</td>
                    <td>false</td>
                    <td class="Active">Active</td>
                    <td>2014-09-23T00:59:26.92</td>
                </tr>
        </tbody>
    </table>
</div>

$('.alertRow.InActive').Parent.click(function () {

    $(this).nextUntil('tr.td.InActive').slideToggle(1000);
});

мой код скрипки

Как я могу это сделать..?

7 ответов


вот код для переключения строк таблицы, которые являются "неактивными". Лучше полагаться на" closest ()", чем" parent () "или" parents ()", потому что это быстрее, и в этом случае имеет смысл использовать его.

$(document).ready(function() {

  // Save all the inactive rows
  var inactive_rows = '';
  $('.InActive').closest("tr").each(function() {
    inactive_rows += '<tr class="alertRow">';
    inactive_rows += $(this).html();
    inactive_rows += '</tr>';
  });
  console.log(inactive_rows);
  // Save all the active rows
  var active_rows = "";
  $('.Active').closest("tr").each(function() {
    active_rows += '<tr class="alertRow">';
    active_rows += $(this).html();
    active_rows += '</tr>';
  });
  // Empty the table
  $('.alertsList').html("");
  // Load the new table
  var table_html = '<table width="100%"><thead><th></th><th>Id</th><th>From</th><th>Action</th><th>State</th><th>time</th></thead><tbody>';
  table_html += active_rows;
  table_html += inactive_rows;
  table_html += '</tbody></table><a href="" class="toggleInactiveRows">Toggle Inactive Rows</a>';
  $('.alertsList').append(table_html);

  // Hide the inactive rows when the page loads
  $('.InActive').closest("tr").hide();

  // Toggle the inactive rows
  $('.toggleInactiveRows').click(function() {
    $('.InActive').closest("tr").slideToggle();
    return false;
  });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="alertsList">
  <table width="100%">
    <thead>
      <th></th>
      <th>Id</th>
      <th>From</th>
      <th>Action</th>
      <th>State</th>
      <th>time</th>
    </thead>
    <tbody>
      <tr class="alertRow">
        <td></td>
        <td>1025973</td>
        <td>SYSTEM</td>
        <td>false</td>
        <td class="Active">Active</td>
        <td>2014-09-23T00:59:26.92</td>
      </tr>
      <tr class="alertRow">
        <td></td>
        <td>1025974</td>
        <td>SYSTEM</td>
        <td>false</td>
        <td class="Active">Active</td>
        <td>2014-09-23T00:59:26.92</td>
      </tr>
      <tr class="alertRow">
        <td></td>
        <td>1025974</td>
        <td>SYSTEM</td>
        <td>false</td>
        <td class="InActive">InActive</td>
        <td>2014-09-23T00:59:26.92</td>
      </tr>
      <tr class="alertRow">
        <td></td>
        <td>1025974</td>
        <td>SYSTEM</td>
        <td>false</td>
        <td class="InActive">InActive</td>
        <td>2014-09-23T00:59:26.92</td>
      </tr>
      <tr class="alertRow">
        <td></td>
        <td>1025974</td>
        <td>SYSTEM</td>
        <td>false</td>
        <td class="Active">Active</td>
        <td>2014-09-23T00:59:26.92</td>
      </tr>
    </tbody>
  </table>
  <a href="" class="toggleInactiveRows">Toggle Inactive Rows</a>
</div>

прежде всего, Jquery неправильно обрабатывает анимацию высоты на элементах таблицы, поэтому мы введем <div>'s внутри <td> ' ы должны быть анимированы, как указано в этом ответ.

во-вторых, поскольку вы хотите переключать неактивные элементы как группу, мы должны сгруппировать их вместе.

  • мы найдем неактивные строки, используя has() метод, оберните их в <tfoot> используя wrapAll() и вставить это перед <tbody>, для чего мы используем insertBefore().

    я использую insertBefore() поскольку это лучшая практика из-за преимущества, упомянутого в этом ответ. Мы можем использовать insertAfter() также, так как семантически нормально включать <tfoot> после <tbody>,

  • затем мы найти the <td>внутри них и оберните их содержимое в скрытый <div> используя wrapInner() метод.

    вы можете избежать этого шага, заполнив таблицу соответственно в serverside

  • затем мы добавляем опцию для переключения до the первый неактивные строки.

  • on щелчок опции переключения, мы используем closest() для доступа к нему родителей <tr> а то nextAll() в цель все следующие <tr>, которые являются неактивными. Затем мы находим <divкоторые мы ввели внутрь них и называем slideToggle() для функции переключения.

    можно использовать parent() для родителей <tr> согласно текущей разметке. Я использую ближайший, чтобы он работал, если вы привязываете обработчик событий к элементу внутри <td> - скажем, например, кнопку.

    мы может использовать siblings() а также для доступа к следующему <tr>, так как мы разделили активные и неактивные строки на разные контейнеры.

    обратите внимание, что нам нужно делегировать обработчик события используя on() С мы вводим опцию переключения динамически.

  • наконец, мы используем псевдоэлемент CSS ::before для отображения соответствующая иконка на основе класса, который переключается, когда пользователь щелкает переключатель с помощью toggleClass()

помимо этого,

  • я завернул столбцы заголовка внутрь <thead>, который является более семантически уместно.
  • я установил минимальную ширину для <td> чтобы избежать "рывка" из-за изменения ширины State столбец, когда видимость всех Inactive товары переключены
  • я удалил пусто <td> и добавил некоторые CSS ради демо

мы в конечном итоге с следующее семантически круто структура, которая составляет складной:

 <table>
   <thead>
     <tr>
          <th> title</th>
     </tr>
   </thead>
   <tfoot>
    <tr>
      <td>Toggle Switch</td>
    </tr>
    <tr>
      <td><div> Collapsible content</div></td>
     </tr>
   </tfoot>
   <tbody>
     <tr>
          <td>body content</td>
     </tr>
   </tbody>
</table>

$('.alertRow').has(".InActive")
// group them together in a tfoot and insert it before tbody
         .insertBefore(".alertsList table tbody").wrapAll("<tfoot></tfoot>")
// inject the hidden divs inside the columns for animating
         .find("td").wrapInner("<div style='display:none'/>").end()
// insert the toggle option before the first inactive row
         .first().before("<tr><td class='toggle' colspan='5'> Inactive Items</td></tr>");

$(".alertsList table").on("click", ".toggle", function () {
   // following class keeps track of the cuurrent state
   $(this).toggleClass("expanded")
   // find all the injected divs and toggle them
      .closest("tr").nextAll("tr").find('td  div').slideToggle(700);
});
*{
  margin:0;
  padding:0;
}
th,td{
  min-width:80px;
  text-align:center;
}
.toggle{
  background:dodgerblue;
}
.toggle::before{
    content:"+"
}
.toggle.expanded::before{
    content:"-"
}
tfoot tr{
  background:#eee;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="alertsList">
    <table width="100%">
        <thead>
          <tr>
                <th>Id</th>
                <th>From</th>
                <th>Action</th>
                <th>State</th>
                <th>time</th>
            </tr>
        </thead>
        <tbody>
            <tr class="alertRow">
                <td>1025973</td>
                <td>SYSTEM</td>
                <td>false</td>
                <td class="Active">Active</td>
                <td>2014-09-23T00:59:26.92</td>
            </tr>
            <tr class="alertRow">
                <td>1025974</td>
                <td>SYSTEM</td>
                <td>false</td>
                <td class="Active">Active</td>
                <td>2014-09-23T00:59:26.92</td>
            </tr>
            <tr class="alertRow">
                <td>1025974</td>
                <td>SYSTEM</td>
                <td>false</td>
                <td class="InActive">InActive</td>
                <td>2014-09-23T00:59:26.92</td>
            </tr>
            <tr class="alertRow">
                <td>1025974</td>
                <td>SYSTEM</td>
                <td>false</td>
                <td class="InActive">InActive</td>
                <td>2014-09-23T00:59:26.92</td>
            </tr>
            <tr class="alertRow">
                <td>1025974</td>
                <td>SYSTEM</td>
                <td>false</td>
                <td class="Active">Active</td>
                <td>2014-09-23T00:59:26.92</td>
            </tr>
        </tbody>
    </table>
</div>

у вас была пара проблем с селекторами:

$('.alertRow .InActive').parent().click(function () {
    $(this).slideToggle(1000);
});

Это должно работать так, как вы задумали.

к сожалению, что касается анимации slideToggle, таблицы, как правило, имеют ограниченный стиль для них. В этом случае slideToggle не будет анимироваться из-за высоты строки tr элементы. Вы можете установить tr line-height и height свойства вручную в CSS, но это может вызвать у вас некоторые другие боли форматирования в будущем. Вот пример скрипка.


как упоминалось в предыдущем посте, вам нужно будет установить line-height и height свойства стиля tr тег для анимационных эффектов для работы.

здесь пример, который переключает все неактивные строки с помощью кнопки.

CSS:

tr {
    height: 15px;
    line-height: 0px;
}

HTML-код:

<div class="alertsList">
<table width="100%">
    <tbody>
        <th></th>
        <th>Id</th>
        <th>From</th>
        <th>Action</th>
        <th>State</th>
        <th>time</th>
        <tr class="alertRow">
            <td></td>
            <td>1025973</td>
            <td>SYSTEM</td>
            <td>false</td>
            <td class="Active">Active</td>
            <td>2014-09-23T00:59:26.92</td>
        </tr>
        <tr class="alertRow">
            <td></td>
            <td>1025974</td>
            <td>SYSTEM</td>
            <td>false</td>
            <td class="Active">Active</td>
            <td>2014-09-23T00:59:26.92</td>
        </tr>
        <tr class="alertRow">
            <td></td>
            <td>1025974</td>
            <td>SYSTEM</td>
            <td>false</td>
            <td class="InActive">InActive</td>
            <td>2014-09-23T00:59:26.92</td>
        </tr>
        <tr class="alertRow">
            <td></td>
            <td>1025974</td>
            <td>SYSTEM</td>
            <td>false</td>
            <td class="InActive">InActive</td>
            <td>2014-09-23T00:59:26.92</td>
        </tr>
        <tr class="alertRow">
            <td></td>
            <td>1025974</td>
            <td>SYSTEM</td>
            <td>false</td>
            <td class="Active">Active</td>
            <td>2014-09-23T00:59:26.92</td>
        </tr>
    </tbody>
</table>
<input id="btnShowHide" type="button" value="Show/hide" />

JS:

 $('#btnShowHide').click(function () {
    $('.InActive').parent('tr').slideToggle(1000);
});

простым решением для этого было бы связать данные таким образом, чтобы сначала активные, а затем неактивные (используйте сортировку для того же).

Если это невозможно, то, вероятно, вы можете использовать ниже код для их сортировки (FYI это будет работать только для тех элементов, которые уже присутствуют в DOM и должны запускаться только один раз)

// a simple compare function, used by the sort below
var compare_rows = function(a, b) {
    var a_val = $(a).find('td.Active').text().toLowerCase();
    var b_val = $(b).find('td.InActive').text().toLowerCase();
    if (a_val > b_val) { return 1; }
    if (a_val < b_val) { return -1; }
    return 0;
};
// the actual sort
$('#tableID tr').sort(compare_rows).appendTo('#tableID');

затем добавьте значок для сворачивания и расширения скрытых

$("<tr class='toggle'><td colspan='5'>Show Hidden Icons</td></tr>").insertBefore($($(".alertsList table tr td.InActive")[0]).parent())

наконец, добавить нажмите даже для динамического значка, добавленного, как показано ниже,

$(".toggle").click(function(){
    $(this).nextAll().slideToggle(1000);
});

надеюсь, что это помогает :)


As Т J сказал в своем ответе, сложно анимировать высоту строки таблицы (см. ответ или ответ для хаков вокруг него, которые включают обертывание содержимого каждой ячейки в <div>).

вы можете вообще пропустить анимацию и просто скрыть или показать неактивные строки:

$('#btnToggle').click(function() {
    $('td.InActive').closest('tr').toggle();
});

если вы хотите, чтобы некоторые визуальные конфеты сигнализировали пользователю о скрытии, я бы предложил использовать .fadeToggle() что будет работа сразу:

$('#btnToggle').click(function() {
    $('td.InActive').closest('tr').fadeToggle(1000);
});

скрипка


в качестве дополнительного Примечания: если вы можете изменить код, который генерирует таблицу (например : PHP или ruby (или wathever) код), попробуйте поместить active / inactive класс строка (the <tr> узел), а не внутренняя ячейка (<td> узел) :

<div class="alertsList">
    <table width="100%">
        <tbody>
            <tr>
                <th></th>
                <th>Id</th>
                <th>From</th>
                <th>Action</th>
                <th>State</th>
                <th>time</th>
            </tr>
            <tr class="alertRow active">
                ...
            </tr>
            <tr class="alertRow active">
                ...
            </tr>
            <tr class="alertRow inactive">
                ...
            </tr>
            <tr class="alertRow inactive">
                ...
            </tr>
            <tr class="alertRow active">
                ...
            </tr>
        </tbody>
    </table>
</div>

это облегчило бы правила в ваших css и js :

//css
tr.inactive {font-style: italic; background-color: #eee}

//js
$('tr.inactive').fadeToggle(1000);

Я создаю это с помощью fadeToggle:

$("table tr td.InActive").each(function(){
    $(this).parent().children(":not(:first-child)").hide();
});

$('a').click(function () {
    $(this).text() == "+" ? $(this).text("-") : $(this).text("+");
    $(this).parents("tr").children(":not(:first-child)").fadeToggle();
});
a{
    text-decoration: none;
}
a:hover{
    text-decoration: underline;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="alertsList">
    <table width="100%">
        <tbody>
            <tr>
                <th></th>
                <th>Id</th>
                <th>From</th>
                <th>Action</th>
                <th>State</th>
                <th>time</th>
                <tr class="alertRow">
                    <td></td>
                    <td>1025973</td>
                    <td>SYSTEM</td>
                    <td>false</td>
                    <td class="Active">Active</td>
                    <td>2014-09-23T00:59:26.92</td>
                </tr>
                <tr class="alertRow">
                    <td></td>
                    <td>1025974</td>
                    <td>SYSTEM</td>
                    <td>false</td>
                    <td class="Active">Active</td>
                    <td>2014-09-23T00:59:26.92</td>
                </tr>
                <tr class="alertRow">
                    <td><a href="#">+</a></td>
                    <td>1025974</td>
                    <td>SYSTEM</td>
                    <td>false</td>
                    <td class="InActive">InActive</td>
                    <td>2014-09-23T00:59:26.92</td>
                </tr>
                <tr class="alertRow">
                    <td><a href="#">+</a></td>
                    <td>1025974</td>
                    <td>SYSTEM</td>
                    <td>false</td>
                    <td class="InActive">InActive</td>
                    <td>2014-09-23T00:59:26.92</td>
                </tr>
                <tr class="alertRow">
                    <td></td>
                    <td>1025974</td>
                    <td>SYSTEM</td>
                    <td>false</td>
                    <td class="Active">Active</td>
                    <td>2014-09-23T00:59:26.92</td>
                </tr>
        </tbody>
    </table>
</div>

Aa вы можете видеть, что я добавил+/ -a элемент для отображения / скрытия неактивных строк.