I am trying to {display:none} on class=”filter-form__group” only if ALL child Input’s are ‘disabled’.
<div class="filter-form__group">
<div class="filter-form__group-filter-wrapper" data-filter-type="list">
<div class="filter-form__list-wrapper">
<ul class="filter-form__list">
<li class="filter-item">
<label data-filter-item="" class="filter-item__content">
<input type="checkbox" value="Luggage" disabled>
</label>
</li>
<li class="filter-item">
<label data-filter-item="" class="filter-item__content">
<input type="checkbox" value="Motorcycle" disabled>
</label>
</li>
</ul>
</div>
</div>
</div>
Thanks!
I tried some CSS but they do not seem to work and I believe this may have to be done in JS.
0
CSS-only solution:
- Hide by default the groups
- Unhide the groups that have at least one input not disabled
.filter-form__group {
display: none;
&:has(input:not(:disabled)) {
display: initial;
}
}
<div class="filter-form__group">
<p>GROUP: all disabled</p>
<input type="checkbox" value="Luggage" disabled>
<input type="checkbox" value="Motorcycle" disabled>
</div>
<div class="filter-form__group">
<p>GROUP one is not disabled</p>
<input type="checkbox" value="Luggage" disabled>
<input type="checkbox" value="Motorcycle">
</div>
Iterate over the potentially disabled elements and push truthy comparisons into an empty array. Then compare the length of the array and input elements nodeList length and add/remove a helper class to the target element accordingly.
function disableGroup(el) {
const group = document.querySelector(el); // get the group parent element
const inputs = group.querySelectorAll('input'); // get inputs
const result = []; // empty array
inputs.forEach(input => { // loop over the inputs
input.disabled ? result.push(true) : null; // if input.disabled push true into array
});
result.length === inputs.length ? // compare the two lengths
group.classList.add('none') : // if they are equal add helper class
group.classList.remove('none') // if not remove helper class
}
disableGroup('.filter-form__group');
disableGroup('.filter-form__group2');
.none {
display: none;
}
Do not display filter-form__group if all input childNodes are disabled
<div class="filter-form__group">
<div class="filter-form__group-filter-wrapper" data-filter-type="list">
<div class="filter-form__list-wrapper">
<ul class="filter-form__list">
<li class="filter-item">
<label data-filter-item="" class="filter-item__content">
Form group 1:<input type="checkbox" value="Luggage" disabled>
</label>
</li>
<li class="filter-item">
<label data-filter-item="" class="filter-item__content">
Form group 1:<input type="checkbox" value="Motorcycle" disabled>
</label>
</li>
</ul>
</div>
</div>
</div>
<div class="filter-form__group2">
<div class="filter-form__group-filter-wrapper" data-filter-type="list">
<div class="filter-form__list-wrapper">
<ul class="filter-form__list">
<li class="filter-item">
<label data-filter-item="" class="filter-item__content">
Form group 2:<input type="checkbox" value="Luggage" disabled>
</label>
</li>
<li class="filter-item">
<label data-filter-item="" class="filter-item__content">
Form group 2:<input type="checkbox" value="Motorcycle">
</label>
</li>
</ul>
</div>
</div>
</div>
It would’ve been nice if you provided an example of what you tried yourself.
Anyway, here’s an (js) idea:
console.log(`wait a sec...`);
setTimeout(disableAllAndMonitor, 2000);
// use a monitoring function to periodically
// check the 'disabled' state of the checkboxes
function monitorDisabledCBs() {
const disabledCheckboxes = document
.querySelectorAll(`.filter-form__group input[type="checkbox"]:not(:disabled)`);
if (disabledCheckboxes.length < 1) {
console.clear();
console.log(`There you have it, div.filter-form__group is hidden`);
return document.querySelector(`.filter-form__group`).style.display = `none`;
}
return setTimeout(monitorDisabledCBs, 500);
}
function disableAllAndMonitor() {
document.querySelectorAll(`input[type="checkbox"]`)
.forEach(cb => cb.disabled = `disabled`);
monitorDisabledCBs();
}
<div class="filter-form__group">
<div class="filter-form__group-filter-wrapper" data-filter-type="list">
<div class="filter-form__list-wrapper">
<ul class="filter-form__list">
<li class="filter-item">
<label data-filter-item="" class="filter-item__content">
<input type="checkbox" value="Luggage" disabled>
</label>
</li>
<li class="filter-item">
<label data-filter-item="" class="filter-item__content">
<input type="checkbox" value="Motorcycle" disabled>
</label>
</li>
</ul>
</div>
</div>
</div>
But I think you’d better use Roko C. Buljan’s answer
Try this, mostly will work
JSfiddle: https://jsfiddle.net/2e34tzjq/
const filterFormGroups = document.querySelectorAll('.filter-form__group');
filterFormGroups.forEach(group => {
const inputs = group.querySelectorAll('input[type="checkbox"]');
const allDisabled = Array.from(inputs).every(input => input.disabled);
if (allDisabled) {
group.style.display = 'none';
}
});
Some cleaner javascript code if you still want to use it over CSS.
function toggleParentHiddenAttribute(parentClass) {
const parentEl = document.querySelector(`.${parentClass}`);
const numberOfInputs = parentEl.querySelectorAll('input').length;
const numberOfHiddenInputs = parentEl.querySelectorAll('input[disabled]').length;
parentEl.hidden = numberOfInputs == numberOfHiddenInputs;
// returning for the console.log
return numberOfInputs == numberOfHiddenInputs
}
let parentClass = 'filter-form__group1';
console.log(parentClass, toggleParentHiddenAttribute(parentClass));
parentClass = 'filter-form__group2';
console.log(parentClass, toggleParentHiddenAttribute(parentClass));
<div class="filter-form__group1">
<div class="filter-form__group-filter-wrapper" data-filter-type="list">
<div class="filter-form__list-wrapper">
<ul class="filter-form__list">
<li class="filter-item">
<label data-filter-item="" class="filter-item__content">
<input type="checkbox" value="Luggage" disabled>
</label>
</li>
<li class="filter-item">
<label data-filter-item="" class="filter-item__content">
<input type="checkbox" value="Motorcycle" disabled>
</label>
</li>
</ul>
</div>
</div>
</div>
<hr/>
<div class="filter-form__group2">
<div class="filter-form__group-filter-wrapper" data-filter-type="list">
<div class="filter-form__list-wrapper">
<ul class="filter-form__list">
<li class="filter-item">
<label data-filter-item="" class="filter-item__content">
<input type="checkbox" value="Luggage">
</label>
</li>
<li class="filter-item">
<label data-filter-item="" class="filter-item__content">
<input type="checkbox" value="Motorcycle" disabled>
</label>
</li>
</ul>
</div>
</div>
</div>
Yep, you’re right—this is something that CSS can’t do. Since you need to check if all the input elements inside a specific group are disabled, JavaScript will work.
Here’s how I would do it:
document.querySelectorAll('.filter-form__group').forEach(function(group) {
const inputItems = group.querySelectorAll('input');
const allDisabled = Array.from(inputItems).every(input => input.disabled);
if (allDisabled) {
group.style.display = 'none';
}
});
3