25 июня (обновлено 26 июля)

Древовидные checkbox

Продолжая тематику предыдущего поста, сегодня речь пойдет о древовидных чекбоксах.
Они опять же чаще всего используются в системе фильтров, когда есть возможность выбрать (или отсеять) группы или подгруппы объектов. При этом немаловажным является не только понятное отображение для пользователя, но также и то, в каком виде запрос будет отправлен серверу.
Я предлагаю несложный рецепт, который вы сможете применить у себя в проекте, соответственно, допилив под свои нужды.


Задана двухуровневая система фильтров (категория\подкатегория), и пользователь может выбрать отдельные подкатегории, либо целую категорию (допустим подкатегория - город; категория - страна).
При выборе категории целиком удобнее оперировать именно ей, а не списком подкатегорий, поэтому на сервер отправим лишь категорию. Если же выбраны не все подкатегории, то отправим список выбранных элементов.

приведу код обработки с комментариями:

 

$(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');
    }

})

 

 

Демо

Скачать