Reputation: 121
I have this page that has multiple checkboxes and when clicked, an element appears.
I have this stripped down version to show it simply:
<!DOCTYPE html>
<html>
<body>
<p>Display some text when the checkbox is checked:</p>
Checkbox 1: <input type="checkbox" id="check1" onclick="box1()"><br>
Checkbox 2: <input type="checkbox" id="check2" onclick="box2()">
<p id="fill">No boxes are checked</p>
<p id="text" style="display:none">Checkbox1 is CHECKED!</p>
<p id="text2" style="display:none">Checkbox2 is CHECKED!</p>
<script>
function box1() {
var checkBox = document.getElementById("check1");
var text = document.getElementById("text");
var fill = document.getElementById("fill");
if (checkBox.checked == true){
text.style.display = "block";
fill.style.display = "none";
} else {
text.style.display = "none";
fill.style.display = "block";
}
}
</script>
<script>
function box2() {
var checkBox = document.getElementById("check2");
var text = document.getElementById("text2");
var fill = document.getElementById("fill");
if (checkBox.checked == true){
text.style.display = "block";
fill.style.display = "none";
} else {
text.style.display = "none";
fill.style.display = "block";
}
}
</script>
</body>
</html>
My problem is that the text shows even a box is checked as shown in the image. How can I do this effectively? thanks!
Upvotes: 0
Views: 955
Reputation: 370779
I'd add the same listener to both checkboxes, and have that listener check the state of both. Then, if both are not checked, display the fill
:
const isCheckeds = document.querySelectorAll('.is-checked');
const fill = document.querySelector('#fill');
function validate() {
let anyChecked = false;
document.querySelectorAll('input').forEach((checkbox, i) => {
if (checkbox.checked) {
anyChecked = true;
}
isCheckeds[i].style.display = checkbox.checked ? 'block' : 'none';
});
fill.style.display = anyChecked ? 'none' : 'block';
}
<p>Display some text when the checkbox is checked:</p>
Checkbox 1: <input type="checkbox" onclick="validate()"><br>
Checkbox 2: <input type="checkbox" onclick="validate()">
<p id="fill">No boxes are checked</p>
<p class="is-checked" style="display:none">Checkbox1 is CHECKED!</p>
<p class="is-checked" style="display:none">Checkbox2 is CHECKED!</p>
Note that inline handlers should be avoided. Strongly consider attaching them properly with Javascript instead. You could also consider using a change
listener instead of a click
listener (for better accessablity), and you could surround the inputs in a <label>
to make them more clickable:
const isCheckeds = document.querySelectorAll('.is-checked');
const fill = document.querySelector('#fill');
const checkboxes = document.querySelectorAll('input');
function validate() {
let anyChecked = false;
checkboxes.forEach((checkbox, i) => {
if (checkbox.checked) {
anyChecked = true;
}
isCheckeds[i].style.display = checkbox.checked ? 'block' : 'none';
});
fill.style.display = anyChecked ? 'none' : 'block';
}
for (const checkbox of checkboxes) {
checkbox.addEventListener('change', validate);
}
<p>Display some text when the checkbox is checked:</p>
<label>Checkbox 1: <input type="checkbox"></label><br>
<label>Checkbox 2: <input type="checkbox"></label>
<p id="fill">No boxes are checked</p>
<p class="is-checked" style="display:none">Checkbox1 is CHECKED!</p>
<p class="is-checked" style="display:none">Checkbox2 is CHECKED!</p>
Upvotes: 2
Reputation: 123397
Javascript is not necessary for this task: with your markup structure you could use CSS
only
:checked ~ p, #cb1, #cb2 {
display: none;
}
#check1:checked ~ #cb1,
#check2:checked ~ #cb2 { display: block; }
<p>Display some text when the checkbox is checked:</p>
Checkbox 1: <input type="checkbox" id="check1"><br>
Checkbox 2: <input type="checkbox" id="check2">
<p id="cb0">No boxes are checked</p>
<p id="cb1">Checkbox1 is checked</p>
<p id="cb2">Checkbox2 is checked!</p>
Upvotes: 1
Reputation: 11
You forgot to define fill through a document.getElementById in the second checkbox. Right now you are disabling the fill on the first checkbox when interacting with the second one. I think this is causing some problems.
Upvotes: 1