Расширение и сворачивание строки таблицы (tr) с помощью jquery
У меня есть таблица с активными и неактивными элементами. Эта таблица динамически заполняется из базы данных. Я пытаюсь добавить переключатель только для неактивных элементов в своей таблице и отобразить все активные элементы. Я имею в виду, что хочу показать все активные элементы и переключить только неактивные элементы в моей таблице.
<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
элемент для отображения / скрытия неактивных строк.