How to show specific text if one specific checkbox is checked among bunch of unique checkboxes

Multi tool use
How to show specific text if one specific checkbox is checked among bunch of unique checkboxes
I have a specific task to do, and I'm not sure what is the best way to do it.
I have around 60 unique checkboxes and when clicked, display some text on their right side (tied to that clicked checkbox).
I have done it with 64 specific eventListeners
, but I'm not sure that this is the best way: I would like to simplify the code.
eventListeners
So, for example, I have bunch of checkboxes in a label that is: test
, test1
, test2
and so on. And when I click on test
checkbox, that the text: "hello world" can appear, if test1
is checked, text: "One 2 three" can appear, if test2
is checked, text: "I've done it" can appear, but if none of them is selected, texts will not be displayed.
test
test1
test2
test
test1
test2
This is the code, one event listener I have now:
var forSale = document.querySelector('#for_sale');
var forSaleEmail = document.querySelector('#for_sale_email');
/*For Sale*/
forSale.addEventListener("click", function(){
if(forSale.checked === true){
forSaleEmail.style.display = 'block';
} else {
forSaleEmail.style.display = 'none';
}
});
Where the forSale
variable is a checkbox and forSaleEmail
is a text that should be displayed.
forSale
forSaleEmail
If you have any suggestions or you can tell me what to look for, it would be greatly appreciated.
HTML Code is as following:
<div><label>For Sale <input type="checkbox" id="for_sale"></label></div>
<div><span id="for_sale_email">
<p>
for sale
</p>
</span></div>
Of course: <label>For Sale <input type="checkbox" id="for_sale"></label> <span id="for_sale_email"> <p> This is for sale </p> </span>
– Goran Sovilj
Jul 1 at 10:37
Perhaps add your html code in the question :)
– Adriano
Jul 1 at 10:37
More of the HTML, not just one
– CertainPerformance
Jul 1 at 10:38
Sorry, added by mistake, all in top question :).
– Goran Sovilj
Jul 1 at 10:42
2 Answers
2
An option is event delegation, where you add one event handler to a parent/ancestor of all the input
's, and use the event property event.target
to detect the one that were clicked on, and simply toggle a class on its parents div
.
input
event.target
div
Combined with the CSS adjacent sibling selector +
it gets as simple as this
+
Note 1: Having a <p>
inside an inline element like a <span>
is not valid markup, so I removed it. If you need an extra, use another <span>
and give it similar style a <p>
has as default.
<p>
<span>
<span>
<p>
Note 2: id
needs to be unique so make sure you have that taken care of, and for your for_sale_email
it doesn't need to be, so I changed it to a class.
id
for_sale_email
Note 3: If you want to "toggle" between the chosen input
's, I also added a code part that does that.
input
Stack snippet
document.querySelector('.inputs_parent').addEventListener('change', function(event) {
// this will "hide" previous checked input
var prev = this.querySelector('div.checked');
if (prev) {
prev.classList.remove('checked');
prev.querySelector('input').checked = false;
}
// remove this "if" statement if won't use the above
if (!prev || !prev.contains(event.target))
event.target.closest('div').classList.toggle('checked');
})
.for_sale_email {
display: none;
}
div.checked + div .for_sale_email {
display: inline-block;
}
<div class="inputs_parent">
<div>
<label>For Sale
<input type="checkbox" id="for_sale1">
</label>
</div>
<div>
<span class="for_sale_email">
for sale
</span>
</div>
<div>
<label>For Sale
<input type="checkbox" id="for_sale2">
</label>
</div>
<div>
<span class="for_sale_email">
for sale
</span>
</div>
<div>
<label>For Sale
<input type="checkbox" id="for_sale3">
</label>
</div>
<div>
<span class="for_sale_email">
for sale
</span>
</div>
<div>
<label>For Sale
<input type="checkbox" id="for_sale4">
</label>
</div>
<div>
<span class="for_sale_email">
for sale
</span>
</div>
</div>
If you can make a small markup change, you can actually accomplish this with CSS alone.
Stack snippet
.inputs_parent label:after {
content: 'X';
display: inline-block;
text-align: center;
font-size: 12px;
color: transparent;
width: 12px;
height: 12px;
border: 1px solid black;
margin-left: 5px;
}
.inputs_parent input,
.inputs_parent .for_sale_email {
display: none;
}
.inputs_parent input:checked + div label:after {
color: black;
}
.inputs_parent input:checked + div + div .for_sale_email {
display: inline-block;
}
<div class="inputs_parent">
<input type="checkbox" id="for_sale1">
<div>
<label for="for_sale1">For Sale
</label>
</div>
<div>
<span class="for_sale_email">
for sale
</span>
</div>
<input type="checkbox" id="for_sale2">
<div>
<label for="for_sale2">For Sale
</label>
</div>
<div>
<span class="for_sale_email">
for sale
</span>
</div>
<input type="checkbox" id="for_sale3">
<div>
<label for="for_sale3">For Sale
</label>
</div>
<div>
<span class="for_sale_email">
for sale
</span>
</div>
<input type="checkbox" id="for_sale4">
<div>
<label for="for_sale4">For Sale
</label>
</div>
<div>
<span class="for_sale_email">
for sale
</span>
</div>
</div>
And this one toggle's the checked items, using an input type="radio"
.
input type="radio"
Stack snippet
.inputs_parent label:after {
content: 'X';
display: inline-block;
text-align: center;
font-size: 12px;
color: transparent;
width: 12px;
height: 12px;
border: 1px solid black;
margin-left: 5px;
}
.inputs_parent input,
.inputs_parent .for_sale_email {
display: none;
}
.inputs_parent input:checked + div label:after {
color: black;
}
.inputs_parent input:checked + div + div .for_sale_email {
display: inline-block;
}
<div class="inputs_parent">
<input type="radio" name="radio" id="for_sale1">
<div>
<label for="for_sale1">For Sale
</label>
</div>
<div>
<span class="for_sale_email">
for sale
</span>
</div>
<input type="radio" name="radio" id="for_sale2">
<div>
<label for="for_sale2">For Sale
</label>
</div>
<div>
<span class="for_sale_email">
for sale
</span>
</div>
<input type="radio" name="radio" id="for_sale3">
<div>
<label for="for_sale3">For Sale
</label>
</div>
<div>
<span class="for_sale_email">
for sale
</span>
</div>
<input type="radio" name="radio" id="for_sale4">
<div>
<label for="for_sale4">For Sale
</label>
</div>
<div>
<span class="for_sale_email">
for sale
</span>
</div>
</div>
The thing is that they have to be under two specific <div>s
– Goran Sovilj
Jul 1 at 10:47
@GoranSovilj Then please edit that into your question, so we can see how it should look like, and I will be able to adjust my answer, as if you can avoid all that javascript you should
– LGSon
Jul 1 at 10:48
@GoranSovilj I will add a script sample to, using 1 event listener
– LGSon
Jul 1 at 10:55
I do apologize, it's now edited.
– Goran Sovilj
Jul 1 at 10:55
@GoranSovilj As the updated code sample of yours can't use CSS, I deleted that part and updated the script sample with your updated code
– LGSon
Jul 1 at 11:26
Your code is totally fine, but you should definetly abstract it into a function:
function selectMessage(checkbockSelector, messageSelector) {
var checkbox = document.querySelector(checkboxSelector);
var message = document.querySelector(messageSelector);
checkbox.addEventListener("click", function(){
message.style.display = checkbox.selected ? 'block' : 'none';
});
}
So that you can just do:
selectMessage("#for_sale", "#for_sale_email");
If there are a lot of elements, it might be a good idea to change the HTML into a structure, that directly relates the labels with the input:
<div id="sale">
<label>For Sale</label>
<input type="checkbox" id="for_sale" class="withhint">
<span class="hint">
<p>for sale</p>
</span>
</div>
Then you can hide them with CSS by default:
.hint { display: none; }
And use javascript to apply the handler to all:
document.querySelectorAll(".withhint").forEach(function(input) {
const hint = input.parentElement.querySelector(".hint");
input.addEventListener("click", function() {
hint.style.display = input.checked ? "block" : "none";
});
});
Try it!
So, i have around 64 unique checkboxes with 64 unique texts. How can i implement this on a higher scale? This is perfect, as i can see, not so complicated :).
– Goran Sovilj
Jul 1 at 10:45
@goran added another way
– Jonas W.
Jul 1 at 10:50
Haha, i'm an idiot. Forgot to add that label and span tag should be separated. i edited my question to show you. THANK YOU SO MUCH.
– Goran Sovilj
Jul 1 at 10:56
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Can you post a section of the HTML?
– CertainPerformance
Jul 1 at 10:35