Как остановить цикл ForEach после нужного результата?
Бьюсь с валидацией. У меня есть несколько чекбоксов один за одним. Если юзер нажимает хотя бы на один чекбокс - валидация этого блока прошла успешно, но таких блоков несколько. Кроме того, мне нужен список ID заполненных чекбоксов для формы отправки. Все блоки с чекбоксами проверяются после нажатия на одну кнопку.
Хочу сделать такую реализацию:
После нажатия кнопки чекбоксы разделяются на два массива: заполненные и пустые. И на каждый массив вешается слушатель. Если юзер сначала не нажал ни на один чекбокс (все чекбоксы - в "пустых") и нажимает на один из пустых - этот элемент удаляется из "пустых" и пушится в "заполненные" - и все массивы опять попадают на проверку.
В ходе работы возникла проблема: мне нужно, чтобы после срабатывания события "change" удалился только чекбокс, на котором произошло событие. А у меня получается, что так как удаление находится внутри цикла, то эта функция рассматривает отловленный инпут не как целевой, а как условие (что условие соблюдено) - и удаляет все элементы из цикла с каждым проходом. Вот сабж заключается в том, как сказать ему "Горшочек - не вари!!!" Чтоб первый раз удалил - и все? Пробовал заменить на цикл "For Of" но не получилось.
let button = document.querySelector("button");
button.addEventListener('click', (e) => {
e.preventDefault();
let emptyInputs = [];
let tempInputs = [];
let inputs = document.querySelectorAll("input[type=checkbox]");
emptyChecker = (e) => {
//for (i of emptyInputs) {
emptyInputs.forEach(function (e, i) {
e.addEventListener('change', function (ev) {
ev.stopPropagation();
if (!e.checked) {
i = null;
throw e;
} else {
if (!tempInputs.includes(e)) {
tempInputs.push(e);
tempChecker(e);
};
emptyChecker(e);
console.log(emptyInputs.length);
emptyInputs.splice(i, 1);
console.log('--- ' + (emptyInputs.length));
return;
}
})
})
}
tempChecker = () => {
tempInputs.forEach(function (e, i) {
e.addEventListener('change', function (ev) {
ev.stopPropagation();
if (!e.checked) {
i = null;
throw e;
} else {
if (!emptyInputs.includes(e)) {
emptyInputs.push(e);
emptyChecker(e);
};
tempChecker(e);
console.log(tempInputs.length);
tempInputs.splice(i, 1);
console.log('--- ' + (tempInputs.length));
return;
}
})
})
}
inputs.forEach((el) => {
if (!el.checked) {
if (!emptyInputs.includes(el)) {
emptyInputs.push(el);
emptyChecker(el);
console.log(emptyInputs.length);
}
} else {
if (!tempInputs.includes(el)) {
tempInputs.push(el);
tempChecker(e);
}
}
})
})
<input type="checkbox" name="another01" id="another01"> Input 1
<input type="checkbox" name="another02" id="another02"> Input 2
<input type="checkbox" name="another03" id="another03"> Input 3
<button type="button" class="button">button</button>
Ответы (1 шт):
А зачем так сложно? Массивы какие-то...
По нажатию кнопки проверки вам нужно выяснить, есть ли в каждом из блоков хотя бы один выбранный чекбокс. Если тут все в порядке, собрать выбранные чекбоксы отдельно.
Что-то типа такого:
UPD: добавил Alarm
let ids; // тут будет финальный список выбранных элементов
let inputs = document.querySelectorAll('input[type=checkbox]');
inputs.forEach(input => {
input.addEventListener('change', () => {
input.parentNode.querySelector('.alarm').classList.remove('active');
});
});
const check = document.querySelector('button');
check.addEventListener('click', () => {
const boxes = document.querySelectorAll('fieldset');
let error = false;
boxes.forEach(box => {
if (!box.querySelectorAll('input:checked').length) {
error = true;
const alarm = box.querySelector('.alarm');
alarm.classList.add('active');
}
});
if (!error) {
ids = document.querySelectorAll('input:checked');
console.log(ids);
}
});
body {
font-family: sans-serif;
}
button,
fieldset {
margin: 1em;
padding: 1em;
}
.alarm {
display: none;
color: #ddd;
border: 3px solid currentColor;
border-radius: 3px;
margin: 0 1em 1em 0;
padding: .5em 1em;
font-weight: 600;
}
.active {
display: inline-block;
margin-right: 100%;
color: red;
}
<fieldset>
<div class="alarm">Alarm!</div>
<input id="form1item1" type="checkbox">lorem ipsum<br>
<input id="form1item2" type="checkbox">dolor sit amet<br>
<input id="form1item3" type="checkbox">consectetur adipiscing elit<br>
</fieldset>
<fieldset>
<div class="alarm">Alarm!</div>
<input id="form2item1" type="checkbox">sed do eiusmod tempor<br>
<input id="form2item2" type="checkbox">incididunt ut labore et dolore magna aliqua<br>
<input id="form2item3" type="checkbox">ut enim ad minim veniam<br>
</fieldset>
<button>check</button>