Развернуть/свернуть строки таблицы с помощью JQuery
Я хочу развернуть и свернуть таблицы таблицы при щелчке столбцов заголовка. Я просто хочу развернуть/свернуть строки, которые находятся под конкретным заголовком (щелкнуть).
Вот моя структура таблицы:
<table border="0">
<tr>
<td colspan="2">Header</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td colspan="2">Header</td>
</tr>
<tr>
<td>date</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
</table>
Любые мысли о том, как я могу выполнить эту задачу. Использование div эта задача кажется довольно простой, но у меня есть табличные данные, которые я хочу манипулировать.
Одна из идей, которую я могу придумать, - использовать класс css в каждой строке, которая различает строки под каждым заголовком и использует JQuery для расширения/сглаживания этих строк только при нажатии на заголовок. Но если мой стол имеет 10-15 заголовков, тогда, кажется, сложно отслеживать классы css.
Пожалуйста, предложите подходящий способ достижения этого.
Ответы
Ответ 1
Вы можете попробовать: -
Дайте классу сказать header
в строках заголовка, используйте nextUntil, чтобы получить все строки под нажатым заголовком до следующего заголовка.
JS
$('.header').click(function(){
$(this).nextUntil('tr.header').slideToggle(1000);
});
Html
<table border="0">
<tr class="header">
<td colspan="2">Header</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
Другой пример:
$('.header').click(function(){
$(this).find('span').text(function(_, value){return value=='-'?'+':'-'});
$(this).nextUntil('tr.header').slideToggle(100); // or just use "toggle()"
});
Вы также можете использовать обещание для переключения значка/текста диапазона после завершения переключения в случае анимированного переключения.
$('.header').click(function () {
var $this = $(this);
$(this).nextUntil('tr.header').slideToggle(100).promise().done(function () {
$this.find('span').text(function (_, value) {
return value == '-' ? '+' : '-'
});
});
});
. prom()
. slideToggle()
Или просто с псевдо-элементом css, чтобы представить знак расширения/сглаживания и просто переключить класс в заголовок.
CSS: -
.header .sign:after{
content:"+";
display:inline-block;
}
.header.expand .sign:after{
content:"-";
}
JS: -
$(this).toggleClass('expand').nextUntil('tr.header').slideToggle(100);
Ответ 2
Самый простой способ добиться этого, не меняя структуру HTML table
, - использовать имя класса в tr
элементах, содержащих заголовок, например .header
, чтобы дать:
<table border="0">
<tr class="header">
<td colspan="2">Header</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr class="header">
<td colspan="2">Header</td>
</tr>
<tr>
<td>date</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
</table>
И jQuery:
// bind a click-handler to the 'tr' elements with the 'header' class-name:
$('tr.header').click(function(){
/* get all the subsequent 'tr' elements until the next 'tr.header',
set the 'display' property to 'none' (if they're visible), to 'table-row'
if they're not: */
$(this).nextUntil('tr.header').css('display', function(i,v){
return this.style.display === 'table-row' ? 'none' : 'table-row';
});
});
JS Fiddle demo.
В связанной демонстрации я использовал CSS, чтобы скрыть элементы tr
, которые не имеют header
class-name; на практике (хотя, несмотря на относительную редкость пользователей с отключенным JavaScript), я бы предложил использовать JavaScript для добавления соответствующих имен классов, скрытия и отображения в зависимости от ситуации:
// hide all 'tr' elements, then filter them to find...
$('tr').hide().filter(function () {
// only those 'tr' elements that have 'td' elements with a 'colspan' attribute:
return $(this).find('td[colspan]').length;
// add the 'header' class to those found 'tr' elements
}).addClass('header')
// set the display of those elements to 'table-row':
.css('display', 'table-row')
// bind the click-handler (as above)
.click(function () {
$(this).nextUntil('tr.header').css('display', function (i, v) {
return this.style.display === 'table-row' ? 'none' : 'table-row';
});
});
JS Fiddle demo.
Литература:
Ответ 3
Я бы сказал, используя атрибут data-
, чтобы соответствовать заголовкам с элементами внутри него. Fiddle: http://jsfiddle.net/GbRAZ/1/
Предварительный просмотр изменения HTML:
<tr class="header" id="header1">
<td colspan="2">Header</td>
</tr>
<tr data-for="header1" style="display:none">
<td>data</td>
<td>data</td>
</tr>
<tr data-for="header1" style="display:none">
<td>data</td>
<td>data</td>
</tr>
Код JS:
$(".header").click(function () {
$("[data-for="+this.id+"]").slideToggle("slow");
});
ИЗМЕНИТЬ:
Но это связано с некоторыми изменениями HTML. поэтому я не знаю, если это то, что вы хотели. Лучшим способом структурирования этого будет использование <th>
или изменение всего html для использования ul, ol, etc
или даже установки div > span
.
Ответ 4
Мне понравился самый простой ответ. Однако мне не нравилась изменчивость рушится. Поэтому я объединил решение этого вопроса: Как использовать функцию slideDown (или показать) в строке таблицы?
чтобы сделать его более плавным, когда строки скользят вверх или вниз. Это связано с необходимостью обертывать содержимое каждого td в div. Это позволяет плавно анимировать свертывание. Когда строки будут расширены, он заменит div только содержимым.
Итак, здесь html:
<table>
<tr class="header">
<td>CARS</td>
</tr>
<tr class="thing">
<td>car</td>
</tr>
<tr class="thing">
<td>truck</td>
</tr>
<tr class="header">
<td>HOUSES</td>
</tr>
<tr class="thing">
<td>split level</td>
</tr>
<tr class="thing">
<td>trailer</td>
</tr>
И здесь js
$('.header').click(function(){
if($(this).hasClass("collapsed")){
$(this).nextUntil('tr.header')
.find('td')
.parent()
.find('td > div')
.slideDown("fast", function(){
var $set = $(this);
$set.replaceWith($set.contents());
});
$(this).removeClass("collapsed");
} else {
$(this).nextUntil('tr.header')
.find('td')
.wrapInner('<div style="display: block;" />')
.parent()
.find('td > div')
.slideUp("fast");
$(this).addClass("collapsed");
}
});
Ознакомьтесь с этой скрипкой для примера
https://jsfiddle.net/p9mtqhm7/52/
Ответ 5
Я расширил один из ответов, однако моя функциональность немного отличается. В моей версии разные строки образуют разные группы. И триггеры "header" запускают сбой/расширение этой конкретной группы. Кроме того, каждая отдельная подгруппа запоминает состояние, в котором оно находится. Это может показаться немного запутанным, вы можете проверить мою версию с помощью jsfiddle. Надеюсь, что этот фрагмент кода будет полезен кому-то там!
HTML
<table border="0">
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
<tr>
<td class='group1'>Group 1</td>
<td>data 2</td>
</tr>
<tr class='group1'>
<td>data 3</td>
<td>data 4</td>
</tr>
<tr>
<td class='group2'>Group 2</td>
<td>data 2</td>
</tr>
<tr class='group2'>
<td>data 3</td>
<td>data 4</td>
</tr>
<tr class='group2'>
<td class='sub_group1'>Sub Group 1</td>
<td>data 6</td>
</tr>
<tr class='group2 sub_group1'>
<td>data 7</td>
<td>data 8</td>
</tr>
<tr class='group2 sub_group1'>
<td>data 9</td>
<td>data 10</td>
</tr>
<tr class='group2 sub_group1'>
<td class='sub_sub_group1'>Sub Sub Group 1</td>
<td>data 11</td>
</tr>
<tr class='group2 sub_group1 sub_sub_group1'>
<td>data 12</td>
<td>data 13</td>
</tr>
<tr class='group2 sub_group1 sub_sub_group1'>
<td>data 14</td>
<td>data 15</td>
</tr>
<tr class='group2'>
<td class='sub_group2'>Sub Group 2</td>
<td>data 11</td>
</tr>
<tr class='group2 sub_group2'>
<td>data 12</td>
<td>data 13</td>
</tr>
<tr class='group2 sub_group2'>
<td>data 14</td>
<td>data 15</td>
</tr>
</table>
CSS
table, tr, td, th
{
border: 1px solid black;
border-collapse:collapse;
}
img.button_open{
content:url('http://code.stephenmorley.org/javascript/collapsible-lists/button-open.png');
cursor:pointer;
}
img.button_closed{
content: url('http://code.stephenmorley.org/javascript/collapsible-lists/button-closed.png');
cursor:pointer;
}
JS
function CreateGroup(group_name)
{
// Create Button(Image)
$('td.' + group_name).prepend("<img class='" + group_name + " button_closed'> ");
// Add Padding to Data
$('tr.' + group_name).each(function () {
var first_td = $(this).children('td').first();
var padding_left = parseInt($(first_td).css('padding-left'));
$(first_td).css('padding-left', String(padding_left + 25) + 'px');
});
RestoreGroup(group_name);
// Tie toggle function to the button
$('img.' + group_name).click(function(){
ToggleGroup(group_name);
});
}
function ToggleGroup(group_name)
{
ToggleButton($('img.' + group_name));
RestoreGroup(group_name);
}
function RestoreGroup(group_name)
{
if ($('img.' + group_name).hasClass('button_open'))
{
// Open everything
$('tr.' + group_name).show();
// Close subgroups that been closed
$('tr.' + group_name).find('img.button_closed').each(function () {
sub_group_name = $(this).attr('class').split(/\s+/)[0];
//console.log(sub_group_name);
RestoreGroup(sub_group_name);
});
}
if ($('img.' + group_name).hasClass('button_closed'))
{
// Close everything
$('tr.' + group_name).hide();
}
}
function ToggleButton(button)
{
$(button).toggleClass('button_open');
$(button).toggleClass('button_closed');
}
CreateGroup('group1');
CreateGroup('group2');
CreateGroup('sub_group1');
CreateGroup('sub_group2');
CreateGroup('sub_sub_group1');
DEMO
Ответ 6
с помощью jQuery легко...
$('YOUR CLASS SELECTOR').click(function(){
$(this).toggle();
});
Ответ 7
Аккордеон JavaScript делает трюк.
Эта скрипта от W3Schools упрощает задачу, просто используя ничего, кроме javascript, который я частично воспроизвожу ниже.
<head>
<style>
button.accordion {
background-color: #eee;
color: #444;
font-size: 15px;
cursor: pointer;
}
button.accordion.active, button.accordion:hover {
background-color: #ddd;
}
div.panel {
padding: 0 18px;
display: none;
background-color: white;
}
div.panel.show {
display: block;
}
</style>
</head><body>
<script>
var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].onclick = function(){
this.classList.toggle("active");
this.nextElementSibling.classList.toggle("show");
}
}
</script>
...
<button class="accordion">Section 1</button>
<div class="panel">
<p>Lorem ipsum dolor sit amet</p>
</div>
...
<button class="accordion">Table</button>
<div class="panel">
<p><table name="detail_table">...</table></p>
</div>
...
<button class="accordion"><table name="button_table">...</table></button>
<div class="panel">
<p>Lorem ipsum dolor sit amet</p>
<table name="detail_table">...</table>
<img src=...></img>
</div>
...
</body></html>
если вы используете php, не забудьте преобразовать "
в '
. Вы также можете использовать таблицы данных внутри кнопки, и они все равно будут работать.