Продолжая тематику предыдущего поста, сегодня речь пойдет о древовидных чекбоксах.
Они опять же чаще всего используются в системе фильтров, когда есть возможность выбрать (или отсеять) группы или подгруппы объектов. При этом немаловажным является не только понятное отображение для пользователя, но также и то, в каком виде запрос будет отправлен серверу.
Я предлагаю несложный рецепт, который вы сможете применить у себя в проекте, соответственно, допилив под свои нужды.
Задана двухуровневая система фильтров (категория\подкатегория), и пользователь может выбрать отдельные подкатегории, либо целую категорию (допустим подкатегория - город; категория - страна).
При выборе категории целиком удобнее оперировать именно ей, а не списком подкатегорий, поэтому на сервер отправим лишь категорию. Если же выбраны не все подкатегории, то отправим список выбранных элементов.
приведу код обработки с комментариями:
$(document).ready(function(){ //Отображаем\скрываем потомков checkbox_ов $('.checkbox-area .spoiler').click(function(){ var block = $(this).parent('li').children('ul'); if ($(block).is(':hidden')){ $(block).slideDown(100); $(this).removeClass('closed'); }else{ $(block).slideUp(100); $(this).addClass('closed'); } return false; }) //Изменение состояния $('.checkbox-area .checkbox input').live('change', function(){ var cur_obj = $(this); // Если выбрано ВСЕ if (!$(cur_obj).is('.all_filter')) $('.checkbox-area input.all_filter').removeAttr('checked').parent().parent('li').removeClass('checked'); if ($(cur_obj).parent().parent('li').find('input:checkbox').length > 1){ // Если это родитель var childinputs = $(cur_obj).parent().parent('li').find('input:checkbox'); // Если текущий объект выбран if ($(cur_obj).is(':checked')){ $(childinputs).removeAttr('checked').parent().parent('li').addClass('checked'); $(cur_obj).attr('checked', 'checked').parent().parent('li').addClass('checked').removeClass('notall'); }else{ $(childinputs).removeAttr('checked').parent().parent('li').removeClass('checked'); } if ($(cur_obj).parent().parent('li').children('a').is('.closed')){ $(cur_obj).parent().parent('li').children('a').removeClass('closed'); $(cur_obj).parent().parent('li').children('ul').slideDown(200); } }else{ // Если это дочерний элемент var parent_li = $(cur_obj).parents('ul.child').parent('li'); if ($(cur_obj).parent().parent('li').is('.checked')){ // Если элемент уже выбран $(cur_obj).parent().parent('li').removeClass('checked'); $(cur_obj).removeAttr('checked'); }else{ // Если мы выбираем этот элемент $(cur_obj).parent().parent('li').addClass('checked'); $(cur_obj).attr('checked','checked'); } var boxes = $(cur_obj).parents('ul.child').find('li'); var boxes_checked = $(cur_obj).parents('ul.child').find('li.checked'); if (boxes.length == boxes_checked.length && boxes_checked.length > 0){ // если были выбраны все $(parent_li).addClass('checked').removeClass('notall').attr('ckecked','ckecked'); $(boxes_checked).find('input').removeAttr('checked'); $(parent_li).children('.checkbox').children('input').attr('checked','checked'); }else{ // если выбраны НЕ все if (boxes_checked.length == 0){ // Совсем ни одного $(cur_obj).parents('ul.child').find('input').removeAttr('checked'); $(parent_li).removeClass('notall'); }else{ $(parent_li).find('.checked').children().children('input').attr('checked','checked'); $(parent_li).addClass('notall').removeClass('checked'); } $(parent_li).removeClass('checked').children('.checkbox').children('input').removeAttr('checked'); } } if ($(cur_obj).is('.all_filter')){ if ($(cur_obj).is(':checked')){ $(cur_obj).parents('ul').find('input:checkbox').removeAttr('checked').parent().parent('li').removeClass('checked').removeClass('notall'); $(cur_obj).parent().parent('li').addClass('checked'); }else{ $(cur_obj).parents('ul').find('input:checkbox').removeAttr('checked').parent().parent('li').removeClass('checked').removeClass('notall'); } } }) // Просчет состояния $('.checkbox-area .checkbox :checked').parents('li').addClass('checked'); $('.checkbox-area ul.child').each(function(){ var cur_obj = $(this); var parent_li = $(cur_obj).parent('li'); var boxes = $(cur_obj).find('li'); var boxes_checked = $(cur_obj).find('li.checked'); if (boxes.length == boxes_checked.length && boxes_checked.length > 0){ // если были выбраны все $(parent_li).addClass('checked').removeClass('notall').attr('ckecked','ckecked'); $(boxes_checked).find('input').removeAttr('checked'); $(parent_li).children('.checkbox').children('input').attr('checked','checked'); }else{ // если выбраны НЕ все if (boxes_checked.length == 0){ // Совсем ни одного $(parent_li).removeClass('notall'); $(parent_li).children('a').addClass('closed'); $(parent_li).children('ul.child').hide(); }else{ $(parent_li).find('.checked').children().children('input').attr('checked','checked'); $(parent_li).addClass('notall').removeClass('checked'); } } if ($(parent_li).children('.checkbox').children('input').is(':checked')){ $(parent_li).find('li').addClass('checked'); $(parent_li).children('a').removeClass('closed'); $(parent_li).children('ul.child').show(); } }) if ($('.checkbox-area input:checkbox:checked').length == 0){ $('.checkbox-area input.all_filter').attr('checked', 'checked').parent().parent('li').addClass('checked'); } })