<html>
<head>
<meta charset='UTF-8'>
<title>Custom and Indeterminate Checkboxes</title>
<link rel='stylesheet' href='css/style.css'>
</head>
<body>
<div id="page-wrap">
<h2>Treeview with Custom Checkboxes and Indeterminate State</h2>
<ul class="treeview">
<li>
<input type="checkbox" name="tall" id="tall">
<label for="tall" class="custom-unchecked">Tall Things</label>
<ul>
<li>
<input type="checkbox" name="tall-1" id="tall-1">
<label for="tall-1" class="custom-unchecked">Buildings</label>
</li>
<li>
<input type="checkbox" name="tall-2" id="tall-2">
<label for="tall-2" class="custom-unchecked">Giants</label>
<ul>
<li>
<input type="checkbox" name="tall-2-1" id="tall-2-1">
<label for="tall-2-1" class="custom-unchecked">Andre</label>
</li>
<li class="last">
<input type="checkbox" name="tall-2-2" id="tall-2-2">
<label for="tall-2-2" class="custom-unchecked">Paul Bunyan</label>
</li>
</ul>
</li>
<li class="last">
<input type="checkbox" name="tall-3" id="tall-3">
<label for="tall-3" class="custom-unchecked">Two sandwiches</label>
</li>
</ul>
</li>
<li class="last">
<input type="checkbox" name="short" id="short">
<label for="short" class="custom-unchecked">Short Things</label>
<ul>
<li>
<input type="checkbox" name="short-1" id="short-1">
<label for="short-1" class="custom-unchecked">Smurfs</label>
</li>
<li>
<input type="checkbox" name="short-2" id="short-2">
<label for="short-2" class="custom-unchecked">Mushrooms</label>
</li>
<li class="last">
<input type="checkbox" name="short-3" id="short-3">
<label for="short-3" class="custom-unchecked">One Sandwich</label>
</li>
</ul>
</li>
</ul>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script src="main.js"></script>
</body>
</html>
* { margin: 0; padding: 0; }
#page-wrap {
margin: auto 0;
}
.treeview {
margin: 10px 0 0 20px;
}
ul {
list-style: none;
}
.treeview li {
background: url(http://jquery.bassistance.de/treeview/images/treeview-default-line.gif) 0 0 no-repeat;
padding: 2px 0 2px 16px;
}
.treeview > li:first-child > label {
/* style for the root element - IE8 supports :first-child
but not :last-child ..... */
}
.treeview li.last {
background-position: 0 -1766px;
}
.treeview li > input {
height: 16px;
width: 16px;
/* hide the inputs but keep them in the layout with events (use opacity) */
opacity: 0;
filter: alpha(opacity=0); /* internet explorer */
filter:"progid:DXImageTransform.Microsoft.Alpha(opacity=0)"; /*IE8*/
}
.treeview li > label {
background: url(https://www.thecssninja.com/demo/css_custom-forms/gr_custom-inputs.png) 0 -1px no-repeat;
/* move left to cover the original checkbox area */
margin-left: -20px;
/* pad the text to make room for image */
padding-left: 20px;
}
/* Unchecked styles */
.treeview .custom-unchecked {
background-position: 0 -1px;
}
.treeview .custom-unchecked:hover {
background-position: 0 -21px;
}
/* Checked styles */
.treeview .custom-checked {
background-position: 0 -81px;
}
.treeview .custom-checked:hover {
background-position: 0 -101px;
}
/* Indeterminate styles */
.treeview .custom-indeterminate {
background-position: 0 -141px;
}
.treeview .custom-indeterminate:hover {
background-position: 0 -121px;
}
$(function() {
$('input[type="checkbox"]').change(checkboxChanged);
function checkboxChanged() {
var $this = $(this),
checked = $this.prop("checked"),
container = $this.parent(),
siblings = container.siblings();
container.find('input[type="checkbox"]')
.prop({
indeterminate: false,
checked: checked
})
.siblings('label')
.removeClass('custom-checked custom-unchecked custom-indeterminate')
.addClass(checked ? 'custom-checked' : 'custom-unchecked');
checkSiblings(container, checked);
}
function checkSiblings($el, checked) {
var parent = $el.parent().parent(),
all = true,
indeterminate = false;
$el.siblings().each(function() {
return all = ($(this).children('input[type="checkbox"]').prop("checked") === checked);
});
if (all && checked) {
parent.children('input[type="checkbox"]')
.prop({
indeterminate: false,
checked: checked
})
.siblings('label')
.removeClass('custom-checked custom-unchecked custom-indeterminate')
.addClass(checked ? 'custom-checked' : 'custom-unchecked');
checkSiblings(parent, checked);
}
else if (all && !checked) {
indeterminate = parent.find('input[type="checkbox"]:checked').length > 0;
parent.children('input[type="checkbox"]')
.prop("checked", checked)
.prop("indeterminate", indeterminate)
.siblings('label')
.removeClass('custom-checked custom-unchecked custom-indeterminate')
.addClass(indeterminate ? 'custom-indeterminate' : (checked ? 'custom-checked' : 'custom-unchecked'));
checkSiblings(parent, checked);
}
else {
$el.parents("li").children('input[type="checkbox"]')
.prop({
indeterminate: true,
checked: false
})
.siblings('label')
.removeClass('custom-checked custom-unchecked custom-indeterminate')
.addClass('custom-indeterminate');
}
}
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.