Как решить проблему с неработающими основными и вложенными чекбоксами?

Я разрабатываю сайт на Django и столкнулся с проблемой, связанной с чекбоксами. В процессе я использую шаблоны Jinja для передачи в HTML-файл двух списков. Первый — это простой строковый список (organ_set_sort), содержащий названия групп, во которые делится второй список. Второй список (tissue_set_sort) представляет собой пары строк [str,str], где первое значение — это собственное название элемента, а второе — название группы, к которой он принадлежит (из списка organ_set_sort). <br/><br/> 

Каждый элемент из обоих списков имеет свой чекбокс, сгруппированный по div-элементам. Важно, что чекбоксы из organ_set_sort и tissue_set_sort находятся в разных div. Мне нужно реализовать функционал, при котором при отметке родительского чекбокса автоматически будут отмечены и все его дочерние чекбоксы. Аналогично, при снятии отметки с родительского чекбокса все дочерние также должны сниматься. Кроме того, хотелось бы, чтобы при снятии отметки со всех дочерних чекбоксов, родительский чекбокс тоже снимался. <br/><br/> 

Вот мой код: <br/><br/> 
<pre><code class="html">&lt;div class="content_organ"&gt;
            &lt;label&gt;&lt;h4&gt;Organe_name&lt;/h4&gt;&lt;/label&gt;
            &lt;!--&lt;input type="text" name="organe"&gt;--&gt;
            &lt;br&gt;
            {% for o in organ_set_sort %}
            &lt;!--o = o.filter(question = qu.id) --&gt;
            &lt;label&gt;&lt;input type="checkbox" name={{o}} value={{o}} id={{o}} onchange="toggleChildren({{o}})"&gt;{{o}}&lt;/label&gt;
            &lt;br&gt;
            {% endfor %}
        &lt;/div&gt;
        &lt;div class="content_tissue"&gt;
            &lt;label&gt;&lt;h4&gt;Tissue_name&lt;/h4&gt;&lt;/label&gt;
            &lt;!--        &lt;input type="text"  name="tissue"&gt;--&gt;
            {% for t in tissue_set_sort %}
            &lt;!--o = o.filter(question = qu.id) --&gt;
  • 28 августа 2024 г. 8:54
Ответы на вопрос 2
Для реализации функциональности, описанной в вашем вопросе, вам нужно будет использовать JavaScript, чтобы отслеживать состояние отмеченных чекбоксов и изменять их состояние в зависимости от взаимодействия с родительскими и дочерними чекбоксами.

Давайте немного модифицируем ваш код и добавим необходимый JavaScript для обработки этой логики.

```html
<div class="content_organ">
    <label><h4>Organe_name</h4></label>
    <br>
    {% for o in organ_set_sort %}
    <label>
        <input type="checkbox" name="{{ o }}" value="{{ o }}" id="{{ o }}" onchange="toggleChildren('{{ o }}')">
        {{ o }}
    </label>
    <br>
    {% endfor %}
</div>
<div class="content_tissue">
    <label><h4>Tissue_name</h4></label>
    <br>
    {% for t in tissue_set_sort %}
    <label>
        <input type="checkbox" name="{{ t.0 }}" value="{{ t.0 }}" class="tissue-checkbox {{ t.1 }}" onchange="checkParent('{{ t.1 }}')">
        {{ t.0 }}
    </label>
    <br>
    {% endfor %}
</div>

<script>
function toggleChildren(parentId) {
    const parentCheckbox = document.getElementById(parentId);
    const childCheckboxes = document.querySelectorAll('.tissue-checkbox.' + parentId);
    
    childCheckboxes.forEach(child => {
        child.checked = parentCheckbox.checked;
    });
}

function checkParent(group) {
    const childCheckboxes = document.querySelectorAll('.tissue-checkbox.' + group);
    const parentCheckbox = document.getElementById(group);
    
    // Проверяем, остались ли дочерние чекбоксы отмеченными
    const allUnchecked = Array.from(childCheckboxes).every(child => !child.checked);
    
    // Снимаем отметку с родительского чекбокса, если все дочерние сняты
    if (allUnchecked) {
        parentCheckbox.checked = false;
    }
}
</script>
```

### Объяснение:
1. **HTML Структура**:
   - Мы добавили класс `tissue-checkbox` к дочерним чекбоксам, а также добавили специальный класс, соответствующий родительскому чекбоксу (группе), к дочерним чекбоксам.
   - Это позволяет нам легко выбирать дочерние чекбоксы по классу.

2. **JavaScript Функции**:
   - `toggleChildren(parentId)`:
     - Эта функция активируется при изменении состояния родительского чекбокса. Она ищет все чекбоксы, которые принадлежат к данной группе, и устанавливает их состояние в то же, что и родительский чекбокс.
   - `checkParent(group)`:
     - Эта функция активируется при изменении состояния дочернего чекбокса. Она проверяет, все ли дочерние чекбоксы находятся в поле "не отмечено". Если да, то состояние родительского чекбокса снимается.

Данный код должен корректно обрабатывать логику взаимодействия между родительскими и дочерними чекбоксами. Убедитесь, что классы и идентификаторы в HTML правильно соответствуют иерархии вашей структуры.
Во-первых, вы пытаетесь искать дочерние чекбоксы внутри родительского элемента. Их, естественно, там быть не может. 
Во-вторых, вы зачем-то прибавляете к id _ и элемент не находится.

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