Я разбирался с одним примером, где зашло в тупик.
Вот мой рабочий код, где вылезла такая ошибка. Тыкал в разной последовательности и по разным чекбоксам. Если по трем шагам сделать нажатиям чекбокса:
1 -> 1.1.2 -> 1
Видно, что не снята галочка indeterminate
// переменная, где массив с чекбоксами
let treeInterest = Array.from(document.querySelectorAll(".interest__check"));
// функция поиска чекбокса
function searchCheckbox() {
// цикл, где перебираем все чекбоксы
for (let i = 0; i < treeInterest.length; i++) {
// вешаем событие на клик изменения чекбокса
treeInterest[i].addEventListener("change", function() {
// переменная на дочерние чекбоксы, где ищет ближайший родительский элемент
let childCheckbox = treeInterest[i]
.closest(".interest")
.querySelectorAll(".interests_active .interest__check");
// условие, если поставить все галочки выведет все иначе снимутся все
treeInterest[i].checked ?
childCheckbox.forEach((elem) => (elem.checked = true)) :
childCheckbox.forEach((elem) => (elem.checked = false));
// поиск ближайшего элемента родителя
let parentActive = treeInterest[i].closest(".interests_active");
// проверка если есть родитель то изменяем чекбоксы через функцию
if (parentActive) {
changeTreeInterest(parentActive);
// поиск родителя
let parentActiveFarther = parentActive
.closest(".interest")
.querySelector(".interest__check")
.closest(".interests_active");
// если родитель есть то изменяем чекбоксы через функцию
if (parentActiveFarther) {
changeTreeInterest(parentActiveFarther);
}
}
});
}
}
// функция изменения чекбоксов родителя
function changeTreeInterest(parentActive) {
// переменные родителей чекбокса
let parentInterest = parentActive.closest(".interest");
let parent = parentInterest.querySelector(".interest__check");
// переменная где массив соседних чекбоксов
let neighborCheckbox = Array.from(
parentActive.querySelectorAll(".interest__check")
);
// массив для значений чекбокса
let childBooleanArray = [];
// перебираем все соседние чекбоксы и пушим в новый массив
neighborCheckbox.forEach((el) => childBooleanArray.push(el.checked));
// переменная истина, если все элементы в массиве истины
let childrenTrue = childBooleanArray.includes(true);
// переменная ложь, если все элементы в массиве ложны
let childrenFalse = childBooleanArray.includes(false);
// если все галочки ложь, то убираем тире у родителя и галочку у родителя
// если все галочки истина, то убираем тире у родителя и ставим галочку у родителя
// если галочки и истина и ложь, то ставим тире родителю и ставим галочку родителю
if (!childrenTrue && childrenFalse) {
parent.indeterminate = false;
parent.checked = false;
} else if (childrenTrue && !childrenFalse) {
parent.indeterminate = false;
parent.checked = true;
} else {
parent.indeterminate = true;
parent.checked = true;
}
}
// вызов функции
searchCheckbox();
<div class="card">
<div class="interests interests_main">
<ul>
<li class="interest">
<label> <input type="checkbox" class="interest__check" />1 </label>
<ul class="interests interests_active">
<li class="interest">
<label> <input type="checkbox" class="interest__check" />1.1 </label>
<!-- Задание повышенной сложности. Раскомментируйте код -->
<ul class="interests interests_active">
<li class="interest">
<label> <input type="checkbox" class="interest__check" />1.1.1 </label>
</li>
<li class="interest">
<label> <input type="checkbox" class="interest__check" />1.1.2 </label>
</li>
</ul>
</li>
<li class="interest">
<label> <input type="checkbox" class="interest__check" />1.2 </label>
<ul class="interests interests_active">
<li class="interest">
<label> <input type="checkbox" class="interest__check" />1.2.1 </label>
</li>
<li class="interest">
<label> <input type="checkbox" class="interest__check" />1.2.2 </label>
</li>
</ul>
</li>
<li class="interest">
<label> <input type="checkbox" class="interest__check" />1.3 </label>
<ul class="interests interests_active">
<li class="interest">
<label> <input type="checkbox" class="interest__check" />1.3.1 </label>
</li>
<li class="interest">
<label> <input type="checkbox" class="interest__check" />1.3.2 </label>
</li>
<li class="interest">
<label> <input type="checkbox" class="interest__check" />1.3.3 </label>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>