JQuery подгруппированные флажки - PullRequest
1 голос
/ 07 февраля 2011

У меня есть список стран.Это разделено на 3 раза.

[ ] World
    [ ] Africa
        [ ] Congo
    [ ] Europe
        [ ] Netherlands, the
        [ ] Italy

Теперь, если я нажму на мир, я хочу, чтобы все они были проверены.Если я нажму на Африку, я только хочу, чтобы Конго было проверено.Если я нажму «Европа», «Италия» и «Нидерланды», следует проверить.Если я нажму Нидерланды, и Италия, нужно проверить Европу, и то же самое должно произойти с World при нажатии на Европу и Африку.Я придумал для этого следующий скрипт jquery:

$(function() {
    $(":checkbox").click(function() {
        var maxlevel = 3;
        var level = $(this).attr("class").substring(5, 6);
        var level_checked = $(this).attr("checked");
        //update children
        $('input', $(this).parent('div')).each(function() {
            var curlevel = $(this).attr("class").substring(5, 6);
            if (curlevel > level) {
                $(this).attr("checked", level_checked);
            }
        });
        //update parents?
    });
});

Я использую следующий HTML-код:

<div>
    <input class="layer1" type="checkbox" />Layer1 <br />
    <div>
        <input class="layer2" type="checkbox" />Layer2 <br />
        <div>
            <input class="layer3" type="checkbox" />Layer3 <br />
            <input class="layer3" type="checkbox" />Layer3 <br />
        </div>
    </div>
    <div>
        <input class="layer2" type="checkbox" />Layer2 <br />
        <div>
            <input class="layer3" type="checkbox" />Layer3 <br />
            <input class="layer3" type="checkbox" />Layer3 <br />
        </div>
    </div>
</div>

Обновление дочерних элементов при нажатии чего-либо работает, но обновляет родителей прищелкнув поле ... Я понятия не имею, как это сделать.Я нашел 2 фрагмента кода, которые сделали это, но они работали только для 1 «подгруппы» флажков, а не для 2, как в моем случае.

Может кто-нибудь помочь мне здесь?

Ответы [ 3 ]

1 голос
/ 07 февраля 2011

Добро пожаловать в класс алгоритмов. Вот основной формат:

Запишите вопрос, как то, на что можно ответить. Это шаг 1.

Шаг 2, запишите ответ в виде последовательности шагов и сделайте каждый шаг максимально подробным.

Шаг 3, преобразуйте каждый конкретный шаг в код или псевдокод (повторите шаг 3 для преобразования псевдокода в код).

Поздравляем, теперь вы реализовали алгоритм в коде. Итак, для вашего конкретного вопроса, я сделаю первые два шага, и позволю вам сделать третий:

Как проверить все родительские флажки данного флажка при его нажатии?

sidenote: это рекурсивная функция. Любой флажок, который вызывается, может нуждаться в этом, но только для проверок, не являющихся братьями и сестрами. Таким образом, у вас есть два пути для рассмотрения. Я рассмотрю маршрут родного брата.

также учтите, что родительский элемент дочернего элемента может быть частично проверяемым или поддерживать только состояния включения / выключения. Я буду называть это SEMI в моих заметках. Вы выберете один путь в зависимости от того, действует ли SEMI.

  • Флажок активирован.
    • Существует два состояния: теперь флажок можно было снять или установить.
  • Если флажок снят,
    • (SEMI) проверка, чтобы проверить, проверены ли какие-либо родственные элементы, и если это так, пометьте родителя как полу-проверенного ИЛИ
    • снимите флажок с родителя, если это состояние полупроверки не поддерживается.
  • Если флажок установлен
    • (SEMI) проверяет, не проверены ли какие-либо элементы одного из родственных элементов, и, если это так, пометьте родительский элемент как полу-проверенный ИЛИ
    • проверить, проверены ли все элементы одного уровня
    • если все братья и сестры отмечены, пометьте родителя как отмеченного
    • иначе пометить родителя как не отмеченного
  • вызовите эту операцию для родительского элемента элемента, если элемент не является корневым элементом

Как проверить все флажки одного из братьев и сестер, чтобы определить их состояние?

  • получить список всех родственных элементов для данного элемента
  • определить переменную для флажка, переменную для непроверенного и переменную для общего количества элементов (счетчик)
  • установите каждый флажок в группе одноуровневых элементов и увеличьте соответствующий счетчик для отмеченного или непроверенного, а также увеличьте переменную счетчика независимо от того, какой другой вы увеличиваете.
  • Если вы определили, все ли братья и сестры не проверены, сравните счетчик с непроверенным
  • Если определяется, не проверены ли какие-либо братья и сестры, сравните непроверенное значение с 0 (больше нуля означает, что хотя бы один не проверен)
  • Если определяется, проверены ли все братья и сестры, сравните счетчик с проверенным
  • Если определяется, проверены ли какие-либо братья и сестры, сравните проверенное значение с 0 (больше нуля означает, что хотя бы один проверен)

Обратите внимание, что существуют более быстрые / простые встроенные методы определения ответа на вопрос №2, но в зависимости от того, как вы его абстрагируете, это простой метод для реализации, требующий обслуживания только в одном месте.


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

Если вы сделаете так, как я вам помог, и напишите длинный код, вы сможете выполнить то, что хотите.

0 голосов
/ 07 февраля 2011

Я думаю, что это будет делать то, что вы хотите. Я пока не смог проверить это. В основном это вызывает щелчок флажка на элементах, которые необходимо проверить, когда он решает, что это необходимо. Это не слишком эффективно, но код довольно прост.

$(function() {
     $(":checkbox").click(function() {
         $this = $(this);
         if $this.is(':checked').length != 0) {
// We are UNCHECKING
             //update children
             $this.siblings('div').children('input').is(':checked').trigger('click');
             //update parents if necessary
             var all_unchecked = true;
             $this.siblings('input').each(function(){
                 if($(this).is(':not(:checked')).length == 0) {all_unchecked = false}
             }
             if (all_unchecked) {
                 $this.parent().siblings('input').is(':checked').trigger('click');
             }); 
         } else {
// We are CHECKING
             //update children
             $this.siblings('div').children('input').is(':not(:checked)').trigger('click');
             //update parents if necessary
             var all_checked = true;
             $this.siblings('input').each(function(){
                 if($(this).is(':checked').length == 0) {all_checked = false}
             }
             if (all_checked) {
                 $this.parent().siblings('input').is(':not(:checked)').trigger('click');
             }); 
        }
    });
}); 
0 голосов
/ 07 февраля 2011
$(function() {
   var uncheck_parent = function(elt) {

   var parent_div = elt.parent("div"),
       parent_cb = parent_div.parent("div").children(":checkbox").first();

    if (parent_cb.length == 0) return;    

    parent_cb.attr("checked", false);
    uncheck_parent(parent_cb);
}

$(":checkbox").click(function() {
    var maxlevel = 3;
    var level = $(this).attr("class").substring(5, 6);
    var level_checked = $(this).attr("checked");
    //update children
    $('input', $(this).parent('div')).each(function() {
        var curlevel = $(this).attr("class").substring(5, 6);
        if (curlevel > level) {
            $(this).attr("checked", level_checked);
        }
    });
    //update parents?
    if (!$(this).is(":checked")) {
       uncheck_parent($(this))
    }
});

});

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...