Как создать свертывающуюся таблицу дерева в html/css/js?
У меня есть некоторые данные для отображения, которые являются как табличными, так и иерархическими. Я хотел бы позволить пользователю иметь возможность разворачивать и сворачивать узлы.
Вроде как, кроме функциональных:
http://www.maxdesign.com.au/articles/tree-table/
Как лучше всего подойти к этому? Я не против использования готового плагина.
6 ответов
SlickGrid обладает этой функциональностью, см. Демонстрацию дерева.
Если вы хотите создать свой собственный, вот пример ( демонстрация jsFiddle): создайте свою таблицу с data-depth
атрибут, чтобы указать глубину элемента в дереве (levelX
CSS-классы предназначены только для оформления отступов):
<table id="mytable">
<tr data-depth="0" class="collapse level0">
<td><span class="toggle collapse"></span>Item 1</td>
<td>123</td>
</tr>
<tr data-depth="1" class="collapse level1">
<td><span class="toggle"></span>Item 2</td>
<td>123</td>
</tr>
</table>
Затем, когда нажимается ссылка переключения, используйте Javascript, чтобы скрыть все <tr>
элементы до <tr>
равной или меньшей глубины (кроме уже свернутых):
$(function() {
$('#mytable').on('click', '.toggle', function () {
//Gets all <tr>'s of greater depth below element in the table
var findChildren = function (tr) {
var depth = tr.data('depth');
return tr.nextUntil($('tr').filter(function () {
return $(this).data('depth') <= depth;
}));
};
var el = $(this);
var tr = el.closest('tr'); //Get <tr> parent of toggle button
var children = findChildren(tr);
//Remove already collapsed nodes from children so that we don't
//make them visible.
//(Confused? Remove this code and close Item 2, close Item 1
//then open Item 1 again, then you will understand)
var subnodes = children.filter('.expand');
subnodes.each(function () {
var subnode = $(this);
var subnodeChildren = findChildren(subnode);
children = children.not(subnodeChildren);
});
//Change icon and hide/show children
if (tr.hasClass('collapse')) {
tr.removeClass('collapse').addClass('expand');
children.hide();
} else {
tr.removeClass('expand').addClass('collapse');
children.show();
}
return children;
});
});
В современных браузерах вам нужно всего лишь немного кода для создания разборного дерева:
var tree = document.querySelectorAll('ul.tree a:not(:last-child)');
for(var i = 0; i < tree.length; i++){
tree[i].addEventListener('click', function(e) {
var parent = e.target.parentElement;
var classList = parent.classList;
if(classList.contains("open")) {
classList.remove('open');
var opensubs = parent.querySelectorAll(':scope .open');
for(var i = 0; i < opensubs.length; i++){
opensubs[i].classList.remove('open');
}
} else {
classList.add('open');
}
e.preventDefault();
});
}
body {
font-family: Arial;
}
ul.tree li {
list-style-type: none;
position: relative;
}
ul.tree li ul {
display: none;
}
ul.tree li.open > ul {
display: block;
}
ul.tree li a {
color: black;
text-decoration: none;
}
ul.tree li a:before {
height: 1em;
padding:0 .1em;
font-size: .8em;
display: block;
position: absolute;
left: -1.3em;
top: .2em;
}
ul.tree li > a:not(:last-child):before {
content: '+';
}
ul.tree li.open > a:not(:last-child):before {
content: '-';
}
<ul class="tree">
<li><a href="#">Part 1</a>
<ul>
<li><a href="#">Item A</a>
<ul>
<li><a href="#">Sub-item 1</a></li>
<li><a href="#">Sub-item 2</a></li>
<li><a href="#">Sub-item 3</a></li>
</ul>
</li>
<li><a href="#">Item B</a>
<ul>
<li><a href="#">Sub-item 1</a></li>
<li><a href="#">Sub-item 2</a></li>
<li><a href="#">Sub-item 3</a></li>
</ul>
</li>
<li><a href="#">Item C</a>
<ul>
<li><a href="#">Sub-item 1</a></li>
<li><a href="#">Sub-item 2</a></li>
<li><a href="#">Sub-item 3</a></li>
</ul>
</li>
<li><a href="#">Item D</a>
<ul>
<li><a href="#">Sub-item 1</a></li>
<li><a href="#">Sub-item 2</a></li>
<li><a href="#">Sub-item 3</a></li>
</ul>
</li>
<li><a href="#">Item E</a>
<ul>
<li><a href="#">Sub-item 1</a></li>
<li><a href="#">Sub-item 2</a></li>
<li><a href="#">Sub-item 3</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#">Part 2</a>
<ul>
<li><a href="#">Item A</a>
<ul>
<li><a href="#">Sub-item 1</a></li>
<li><a href="#">Sub-item 2</a></li>
<li><a href="#">Sub-item 3</a></li>
</ul>
</li>
<li><a href="#">Item B</a>
<ul>
<li><a href="#">Sub-item 1</a></li>
<li><a href="#">Sub-item 2</a></li>
<li><a href="#">Sub-item 3</a></li>
</ul>
</li>
<li><a href="#">Item C</a>
<ul>
<li><a href="#">Sub-item 1</a></li>
<li><a href="#">Sub-item 2</a></li>
<li><a href="#">Sub-item 3</a></li>
</ul>
</li>
<li><a href="#">Item D</a>
<ul>
<li><a href="#">Sub-item 1</a></li>
<li><a href="#">Sub-item 2</a></li>
<li><a href="#">Sub-item 3</a></li>
</ul>
</li>
<li><a href="#">Item E</a>
<ul>
<li><a href="#">Sub-item 1</a></li>
<li><a href="#">Sub-item 2</a></li>
<li><a href="#">Sub-item 3</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#">Part 3</a>
<ul>
<li><a href="#">Item A</a>
<ul>
<li><a href="#">Sub-item 1</a></li>
<li><a href="#">Sub-item 2</a></li>
<li><a href="#">Sub-item 3</a></li>
</ul>
</li>
<li><a href="#">Item B</a>
<ul>
<li><a href="#">Sub-item 1</a></li>
<li><a href="#">Sub-item 2</a></li>
<li><a href="#">Sub-item 3</a></li>
</ul>
</li>
<li><a href="#">Item C</a>
<ul>
<li><a href="#">Sub-item 1</a></li>
<li><a href="#">Sub-item 2</a></li>
<li><a href="#">Sub-item 3</a></li>
</ul>
</li>
<li><a href="#">Item D</a>
<ul>
<li><a href="#">Sub-item 1</a></li>
<li><a href="#">Sub-item 2</a></li>
<li><a href="#">Sub-item 3</a></li>
</ul>
</li>
<li><a href="#">Item E</a>
<ul>
<li><a href="#">Sub-item 1</a></li>
<li><a href="#">Sub-item 2</a></li>
<li><a href="#">Sub-item 3</a></li>
</ul>
</li>
</ul>
</li>
</ul>
(см. также эту скрипку)
Jquery твой друг здесь.
http://docs.jquery.com/UI/Tree
Если вы хотите сделать свой собственный, вот несколько рекомендаций высокого уровня:
Показать все ваши данные как <ul />
элементы с внутренними данными как вложенные <ul />
и затем используйте jquery:
$('.ulClass').click(function(){ $(this).children().toggle(); });
Я считаю, что это правильно. Что-то вроде того.
РЕДАКТИРОВАТЬ:
Вот полный пример.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
</head>
<body>
<ul>
<li><span class="Collapsable">item 1</span><ul>
<li><span class="Collapsable">item 1</span></li>
<li><span class="Collapsable">item 2</span><ul>
<li><span class="Collapsable">item 1</span></li>
<li><span class="Collapsable">item 2</span></li>
<li><span class="Collapsable">item 3</span></li>
<li><span class="Collapsable">item 4</span></li>
</ul>
</li>
<li><span class="Collapsable">item 3</span></li>
<li><span class="Collapsable">item 4</span><ul>
<li><span class="Collapsable">item 1</span></li>
<li><span class="Collapsable">item 2</span></li>
<li><span class="Collapsable">item 3</span></li>
<li><span class="Collapsable">item 4</span></li>
</ul>
</li>
</ul>
</li>
<li><span class="Collapsable">item 2</span><ul>
<li><span class="Collapsable">item 1</span></li>
<li><span class="Collapsable">item 2</span></li>
<li><span class="Collapsable">item 3</span></li>
<li><span class="Collapsable">item 4</span></li>
</ul>
</li>
<li><span class="Collapsable">item 3</span><ul>
<li><span class="Collapsable">item 1</span></li>
<li><span class="Collapsable">item 2</span></li>
<li><span class="Collapsable">item 3</span></li>
<li><span class="Collapsable">item 4</span></li>
</ul>
</li>
<li><span class="Collapsable">item 4</span></li>
</ul>
<script type="text/javascript">
$(".Collapsable").click(function () {
$(this).parent().children().toggle();
$(this).toggle();
});
</script>
Я тоже брошу jsTree на ринг. Я нашел это довольно адаптируемым к вашей конкретной ситуации. Он упакован как плагин jQuery.
Он может работать из разных источников данных, но мой любимый - простой вложенный список, как описано в @joe_coolish или здесь:
<ul>
<li>
Item 1
<ul>
<li>Item 1.1</li>
...
</ul>
</li>
...
</ul>
Эта структура постепенно переходит в статическое дерево, когда JS недоступен в клиенте, и ее достаточно легко читать и понимать с точки зрения кодирования.
HTML 5 позволяет итоговый тег, элемент details. Это может быть использовано, чтобы просмотреть или скрыть (свернуть / развернуть) раздел. Ссылка на сайт
Вы можете попробовать jQuery treegrid ( http://maxazan.github.io/jquery-treegrid/) или jQuery treetable ( http://ludo.cubicphuse.nl/jquery-treetable/)
Оба используют HTML <table>
Формат тега и стилизованный под дерево.
Древовидная таблица jQuery использует data-tt-id
а также data-tt-parent-id
для определения родителя и потомка дерева. Пример использования:
<table id="tree">
<tr data-tt-id="1">
<td>Parent</td>
</tr>
<tr data-tt-id="2" data-tt-parent-id="1">
<td>Child</td>
</tr>
</table>
$("#tree").treetable({ expandable: true });
Тем временем jQuery treegrid использует только класс для стилизации дерева. Пример использования:
<table class="tree">
<tr class="treegrid-1">
<td>Root node</td><td>Additional info</td>
</tr>
<tr class="treegrid-2 treegrid-parent-1">
<td>Node 1-1</td><td>Additional info</td>
</tr>
<tr class="treegrid-3 treegrid-parent-1">
<td>Node 1-2</td><td>Additional info</td>
</tr>
<tr class="treegrid-4 treegrid-parent-3">
<td>Node 1-2-1</td><td>Additional info</td>
</tr>
</table>
<script type="text/javascript">
$('.tree').treegrid();
</script>