jQuery / Twitter Bootstrap List Tree Plugin
https://gist.github.com/3317341
HTML
<script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.0.4/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.0.4/css/bootstrap-combined.min.css">
<script src="http://underscorejs.org/underscore-min.js"></script>
<div id="content">
<div class="listTree"></div>
<button class="btn btn-success">Check All</button>
<button class="btn btn-danger">Un-Check All</button>
<button class="btn btn-info">Expand All</button>
<button class="btn btn-warning">Collapse All</button>
<button class="btn btn-inverse">Change Data</button>
<br /><br />
<h4>Selection JSON:</h4>
<pre id="selectionJson"></pre>
<button class="btn btn-primary">Get JSON for selected nodes</button>
</div>
CSS
/* Don't mind me... */
#content {
margin: 20px;
}
/* Relevant to the plugin. */
.listTree {
margin-bottom: 18px;
}
.listTree ul {
margin: 0;
}
.listTree li {
list-style-type: none;
}
.listTree > ul > li {
background-color: #eee;
border-width: 1px 1px 0 1px;
border-style: solid;
border-color: #ddd;
}
.listTree > ul > li:first-child {
border-width: 1px 1px 0 1px;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
}
.listTree > ul > li:last-child {
border-width: 1px;
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
}
.listTree > ul > li:last-child > ul > li:last-child {
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
}
.listTree span {
display: inline-block;
width: 100%;
padding: 5px;
}
.listTree > ul > li > span {
font-weight: bold;
}
.listTree > ul > li > ul > li {
background-color: #fff;
border-width: 1px 0 0 0;
border-style: solid;
border-color: #ddd;
padding-left: 10px;
}
.listTree > ul > li > ul > li:first-child {
border-width: 1px 0 0 0;
}
.listTree > ul > li > ul > li:last-child {
border-width: 1px 0 0 0;
}
.listTree i {
float: right;
margin-right: 15px;
}
JavaScript
/*
* Copyright 2012 Clay Walker
* Licensed under GPLv2 ONLY
*/
(function ($) {
var template = '\
<ul>\
<% _.each(context, function(parent, index) { %>\
<li>\
<span><input value="<%= parent.key %>" id="<%= parent.id%>"/> <a class="icon-plus"></a> <a class="icon-minus"></a> <% if (index > 0) { %><a class="icon-arrow-up"></a> <% } if (index < context.length-1) {%><a class="icon-arrow-down"></a><%}%><i class="icon-chevron-up icon-black"></i></span>\
<% if (options.startCollapsed && !options.visibleParents[parent.id]) { %>\
<ul style="display: none;">\
<% } else { %>\
<ul >\
<% } %>\
<% _.each(parent.values, function(child, index) { %>\
<li>\
<span><input value="<%= child.key %>" id="<%= child.id %>"/> <a class="icon-minus"></a> <% if (index > 0) { %> <a class="icon-arrow-up"></a> <% } if (index < parent.values.length-1) {%><a class="icon-arrow-down"></a><%}%></span>\
</li>\
<% }); %>\
</ul>\
</li>\
<% }); %>\
</ul>';
var templateParent = '<li>\
<span><input value="<%= key %>" id="<%= id %>"/> <a class="icon-plus"></a> <a class="icon-minus"></a><i class="icon-chevron-up icon-black"></i></span>\
<ul style="display: none;">\
</li>';
var templateChild = '<li>\
<span><input value="<%= key %>" id="<%= id %>"/> <a class="icon-minus"></a></span>\
</li>';
/** Check all child checkboxes.
* @param jQElement The parent <li>.
*/
function _selectAllChildren(jQElement) {
jQElement.find('ul > li > span > input[type="checkbox"]')
.each(function () {
$(this).prop('checked', true);
});
}
/** Uncheck all child checkboxes.
* @param jQElement The parent <li>.
...