Skip to content

Instantly share code, notes, and snippets.

@serjnazarov
Last active October 26, 2018 12:53
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save serjnazarov/19ef6e5f64903b271fe9 to your computer and use it in GitHub Desktop.
Save serjnazarov/19ef6e5f64903b271fe9 to your computer and use it in GitHub Desktop.
Just a simple JQuery-based checkbox tree with sweet manners :-) Tree is expandable, checkboxes have logical actions and may be indeterminate. This example uses Russian regions, but you can use anything. Fieldset MUST wrap every category with sub-categories. Form must has id="tree". Use Bootstrap for better results!
<!DOCTYPE html>
<html>
<head>
<meta charset="utf8">
<!-- <link rel="stylesheet" href="./bootstrap.min.css"> -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script>
$(function() {
$('form#tree legend').on('click', function() {
if ($(this).text() == "+") {$(this).text("-");}
else {$(this).text("+");}
//console.log(this);
//console.log("click");
var currthread = $(this).parent("fieldset");
$(currthread).children("fieldset").toggleClass("closed");
});
$("input:checkbox").on('change', function() {
var currcheck = $(this).closest("fieldset").has("fieldset");
//отмечаем или снимаем отметку с детей
if ($(this).prop("checked") == true){
//console.log("true");
$(currcheck).find("input:checkbox").prop({"checked":true, "indeterminate":false}); //почему-то надо снимать "indeterminate"
} else {
//console.log("false");
$(currcheck).find("input:checkbox").prop({"checked":false, "indeterminate":false}); //почему-то надо снимать "indeterminate"
}
//все ПРЯМЫЕ предки чекбокса становятся indeterminate
var currdeterm = $(this).closest("fieldset");
$(currdeterm).parentsUntil( $("form#tree"), "fieldset").each(function(){
//console.log(this);
$(this).find("input:checkbox:first").prop({"indeterminate":true, "checked":false});
});
//теперь проверим всех родителей-fieldset'ов этого чекбокса до самого верха. Каждого родителя надо проверить на чекнутость детей
$(this).parentsUntil( $("form#tree"), "fieldset").has("fieldset").each(function(){
var chkbx = $(this).find("input:checkbox").not(":first"); //выбираем всех чекбоксов-детей-внуков и т.д.
var chkd = $(this).find("input:checkbox:checked"); //выбираем чекнутые чекбоксы среди детей
//console.log("всего: " + chkbx.length + "," + "чекнутых: " + chkd.length);
if (chkd.length == chkbx.length) { //если кол-во чекнутых равно общему кол-ву чекбоксов, то чекаем и этот чекбокс
$(this).find("input:checkbox:first").prop({"indeterminate":false, "checked":true});
}
});
});
});
</script>
<style>
form#tree fieldset {
margin: 0 0 0 15px;
padding: 0;
/*border: solid 1px black;*/
}
form#tree fieldset legend {
margin: -22px -10px -22px -10px;
width: auto;
font-size:14px;
border:0;
cursor:pointer;
}
form#tree fieldset.closed {
margin: 0 0 0 15px;
padding: 0;
/*border: solid 1px black;*/
display:none;
}
div.checkbox {
margin: 3px;
}
</style>
</head>
<body>
<div class="row">
<div class="col-md-4 col-md-offset-1">
<form id="tree" role="form">
<!--<div class="form-group">-->
<fieldset name="1"><legend>+</legend>
<div class="checkbox">
<label class="control-label"><input type="checkbox" name="russia">Россия</label>
</div>
<fieldset name="2" class="closed"><legend>+</legend>
<div class="checkbox">
<label class="control-label"><input type="checkbox">УРФО</label>
</div>
<fieldset name="3" class="closed"><legend>+</legend>
<div class="checkbox">
<label class="control-label"><input type="checkbox">Челябинская область</label>
</div>
<fieldset name="4" class="closed">
<div class="checkbox">
<label class="control-label"><input type="checkbox">Миасс</label>
</div>
<div class="checkbox">
<label class="control-label"><input type="checkbox">Златоуст</label>
</div>
</fieldset>
</fieldset>
<fieldset name="3" class="closed"><legend>+</legend>
<div class="checkbox">
<label class="control-label"><input type="checkbox">Курганская область</label>
</div>
<fieldset name="4" class="closed">
<div class="checkbox">
<label class="control-label"><input type="checkbox">Курган</label>
</div>
<div class="checkbox">
<label class="control-label"><input type="checkbox">Щучье</label>
</div>
</fieldset>
</fieldset>
</fieldset>
<fieldset name="22" class="closed"><legend>+</legend>
<div class="checkbox">
<label class="control-label"><input type="checkbox">ЦФО</label>
</div>
<fieldset name="23" class="closed"><legend>+</legend>
<div class="checkbox">
<label class="control-label"><input type="checkbox">Москва и область</label>
</div>
<fieldset name="24" class="closed">
<div class="checkbox">
<label class="control-label"><input type="checkbox">Москва</label>
</div>
<div class="checkbox">
<label class="control-label"><input type="checkbox">Зеленоград</label>
</div>
<div class="checkbox">
<label class="control-label"><input type="checkbox">Зеленоград</label>
</div>
</fieldset>
</fieldset>
</fieldset>
</fieldset>
<!--</div>-->
</form>
</div>
</div>
</body>
</html>
@serjnazarov
Copy link
Author

JQuery library is required.
You can divide this code to .html, .css and .js files by yourself.
Don't forget to wrap in

every category of your tree.
Form must have id="tree", but you can change this in JS code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment