This commit is contained in:
Ilya Kantor 2014-10-26 22:10:13 +03:00
parent 06f61d8ce8
commit f301cb744d
2271 changed files with 103162 additions and 0 deletions

View file

@ -0,0 +1 @@
{"name":"checkbox-tree","plunk":"XexJRV6rO0w15179jqGC"}

View file

@ -0,0 +1,23 @@
var result = {
0: { children: [] }
};
$('div[id^="region"]').each(function() {
el = $(this);
var id = el.attr('id').slice(6);
result[id] = {
title: el.children('label').html(),
children: [],
id: id
};
var parent = el.parent().closest('div[id^="region"]');
if (parent.length) {
var pid = parent.attr('id').slice(6);
} else {
pid = 0;
}
result[pid].children.push(+id);
});

View file

@ -0,0 +1,75 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<link href="tree.css" rel="stylesheet">
<script src="http://code.jquery.com/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
<script src="regions.js"></script>
<script src="tree.js"></script>
</head>
<body>
<script id="tree-template" type="text/template">
<ul>
<% $(children).each(function() {
var nodeData = data[this];
var hasChildren = nodeData.children && nodeData.children.length;
%>
<li data-id="<%=nodeData.id%>" class="<%=hasChildren ? 'tree-closed' : ''%>">
<% if (hasChildren) { %> <span class="tree-toggler"></span> <% } %>
<input type="checkbox" value="<%=nodeData.id%>">
<%=nodeData.title%>
</li>
<% }); %>
</ul>
</script>
<script>
// требование - как можно меньше DOM-элементов
// работа с данными из 1000 узлов
/* пример структуры данных
var data = [
{
children: [1,2,3]
},
{
title: 'Россия',
id: 1,
children: [4,5]
},
{
title: 'Украина',
id: 2
},
{
title: 'Беларусь',
id: 3
},
{
title: 'Север',
id: 4
},
{
title: 'Юг',
id: 5
}
];
*/
var tree = new Tree({
template: _.template($('#tree-template').html().trim()),
data: regions
});
tree.getElement().appendTo('body');
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,37 @@
.tree, .tree ul {
list-style: none;
margin: 0;
padding: 2px;
}
.tree .tree-open ul {
display: block;
}
.tree .tree-closed ul {
display: none;
}
.tree-toggler {
color: blue;
cursor: pointer;
float: left;
margin-left: -16px;
width: 1em;
height: 1em;
}
.tree-open .tree-toggler {
background: url(http://js.cx/tree/minus.gif) no-repeat center;
}
.tree-closed .tree-toggler {
background: url(http://js.cx/tree/plus.gif) no-repeat center;
}
.tree li {
line-height: 1em;
padding-left: 16px;
}

View file

@ -0,0 +1,74 @@
function Tree(options) {
var self = this;
var template = options.template;
var data = options.data;
this.getElement = function() {
if (!this.elem) render();
return this.elem;
}
function onTogglerClick(e) {
self.toggle( $(e.currentTarget.parentNode) );
}
function onCheckboxChange(e) {
var checked = e.target.checked;
var id = e.target.value;
var node = $(e.currentTarget.parentNode);
if (checked) {
self.open(node);
}
node.find('input').prop('checked', checked);
}
this.toggle = function(node) {
ensureChildrenRendered(node);
node.toggleClass("tree-open tree-closed");
};
this.open = function(node) {
ensureChildrenRendered(node);
node.addClass("tree-open").removeClass("tree-closed");
}
this.close = function(node) {
ensureChildrenRendered(node);
node.addClass("tree-closed").removeClass("tree-open");
}
function ensureChildrenRendered(node) {
var ul = node.children('ul');
if (!ul.length) {
renderChildren( node.data('id') ).appendTo(node);
if (node.children('input').is(':checked')) {
node.find('input').prop('checked', true);
}
}
}
function renderChildren(id) {
return $(template({
children: data[id].children,
data: data
}));
}
function render() {
self.elem = renderChildren(0)
.addClass('tree');
self.elem.on('click', '.tree-toggler', onTogglerClick);
self.elem.on('change', 'input', onCheckboxChange);
}
}