Reputation: 408
I have a series of checkboxes that can accept multiple "checks." What I want to have is have a div shown for every checkbox checked.
I have it set up to capture the value of every checkbox and store it in an array. But now I'm trying to figure out how to display each element for every case, e.g., If A is selected, show A; if A and B are selected, show A & B, etc.
I started doing this as a series of if...then statements, but I feel like that will quickly become unwieldily. Then I thought about using "switch" but couldn't get that to work. Anyone have any thoughts?
function GetSelected() {
var selected = new Array();
var tblFruits = document.getElementById("tblFruits");
var chks = tblFruits.getElementsByTagName("INPUT");
for (var i = 0; i < chks.length; i++) {
if (chks[i].checked) {
selected.push(chks[i].value);
}
}
if (selected.includes("1")) {
document.getElementById("mango").style.display = "block";
}
else if (selected.includes("1") && selected.includes("2")) {
document.getElementById("mango").style.display = "block" ;
document.getElementById("apple").style.display = "block" ;
}
else {
console.log("Oops");
}
console.log(selected.includes("2"));
}
#mango, #apple, #banana, #guava, #orange {
display: none;
}
<table id="tblFruits">
<tr>
<td><input id="chkMango" type="checkbox" value="1"/><label for="chkMango">Mango</label></td>
</tr>
<tr>
<td><input id="chkApple" type="checkbox" value="2"/><label for="chkApple">Apple</label></td>
</tr>
<tr>
<td><input id="chkBanana" type="checkbox" value="3"/><label for="chkBanana">Banana</label></td>
</tr>
<tr>
<td><input id="chkGuava" type="checkbox" value="4"/><label for="chkGuava">Guava</label></td>
</tr>
<tr>
<td><input id="chkOrange" type="checkbox" value="5"/><label for="chkOrange">Orange</label></td>
</tr>
</table>
<br />
<input type = "button" value = "Get" onclick = "GetSelected()" />
<p> </p>
<div class="wrapper">
<div id="mango">Mango</div>
<div id="apple">Apple</div>
<div id="banana">Banana</div>
<div id="guava">Guava</div>
<div id="orange">Orange</div>
</div>
Upvotes: 0
Views: 120
Reputation: 1046
In your solution selected array contains entire htmlElement and not just value of the checkbox, but you are treating array as in it contains only value. This will solve your problem 😉
function clearSelection() {
const divs = document.querySelectorAll('.wrapper > div');
[...divs].forEach(div => {
div.style.display = 'none';
});
}
function GetSelected() {
clearSelection()
var tblFruits = document.getElementById("tblFruits");
var chks = tblFruits.getElementsByTagName("INPUT");
const selected = Array.prototype.filter.call(chks, checkbox => checkbox.checked).map(data => data.id);
selected.forEach(id => {
var resultId = id.slice(3).toLowerCase();
document.getElementById(resultId).style.display = 'block';
})
}
#mango, #apple, #banana, #guava, #orange {
display: none;
}
<table id="tblFruits">
<tr>
<td><input id="chkMango" type="checkbox" value="1"/><label for="chkMango">Mango</label></td>
</tr>
<tr>
<td><input id="chkApple" type="checkbox" value="2"/><label for="chkApple">Apple</label></td>
</tr>
<tr>
<td><input id="chkBanana" type="checkbox" value="3"/><label for="chkBanana">Banana</label></td>
</tr>
<tr>
<td><input id="chkGuava" type="checkbox" value="4"/><label for="chkGuava">Guava</label></td>
</tr>
<tr>
<td><input id="chkOrange" type="checkbox" value="5"/><label for="chkOrange">Orange</label></td>
</tr>
</table>
<br />
<input type = "button" value = "Get" onclick = "GetSelected()" />
<p> </p>
<div class="wrapper">
<div id="mango">Mango</div>
<div id="apple">Apple</div>
<div id="banana">Banana</div>
<div id="guava">Guava</div>
<div id="orange">Orange</div>
</div>
Upvotes: 1
Reputation: 171690
You are over complicating this. There is a one to one relationship between the checkboxes and the content elements.
Just loop over the checkboxes and parse their id to get the associated content id and within that loop update the display of the associated content element every iteration.
Or do the reverse , loop over the content elements and see if the associated checkbox is checked.
You could make it even simpler by setting the values as the content id and skip a line of parsing the checkbox id. Then the content id would be el.value
function GetSelected() {
document.querySelectorAll('#tblFruits input').forEach((el) => {
const contentId = el.id.replace('chk', '').toLowerCase()
document.getElementById(contentId).style.display = el.checked ? 'block' : 'none';
});
}
#mango,
#apple,
#banana,
#guava,
#orange {
display: none;
}
<table id="tblFruits">
<tr>
<td><input id="chkMango" type="checkbox" value="1" /><label for="chkMango">Mango</label></td>
</tr>
<tr>
<td><input id="chkApple" type="checkbox" value="2" /><label for="chkApple">Apple</label></td>
</tr>
<tr>
<td><input id="chkBanana" type="checkbox" value="3" /><label for="chkBanana">Banana</label></td>
</tr>
<tr>
<td><input id="chkGuava" type="checkbox" value="4" /><label for="chkGuava">Guava</label></td>
</tr>
<tr>
<td><input id="chkOrange" type="checkbox" value="5" /><label for="chkOrange">Orange</label></td>
</tr>
</table>
<br />
<input type="button" value="Get" onclick="GetSelected()" />
<p> </p>
<div class="wrapper">
<div id="mango">Mango</div>
<div id="apple">Apple</div>
<div id="banana">Banana</div>
<div id="guava">Guava</div>
<div id="orange">Orange</div>
</div>
Upvotes: 2
Reputation: 1212
Try like this
checkbox value and fruits div having relation. If checkbox banana is checked then div
with id banana
will get displyed and other div style will set to display:none
.
<table id="tblFruits">
<tr>
<td><input id="chkMango" type="checkbox" value="mango"/><label for="chkMango">Mango</label></td>
</tr>
<tr>
<td><input id="chkApple" type="checkbox" value="apple"/><label for="chkApple">Apple</label></td>
</tr>
<tr>
<td><input id="chkBanana" type="checkbox" value="banana"/><label for="chkBanana">Banana</label></td>
</tr>
<tr>
<td><input id="chkGuava" type="checkbox" value="guava"/><label for="chkGuava">Guava</label></td>
</tr>
<tr>
<td><input id="chkOrange" type="checkbox" value="orange"/><label for="chkOrange">Orange</label></td>
</tr>
</table>
<br />
<input type = "button" value = "Get" onclick = "GetSelected()" />
<p> </p>
<div class="wrapper">
<div id="mango">Mango</div>
<div id="apple">Apple</div>
<div id="banana">Banana</div>
<div id="guava">Guava</div>
<div id="orange">Orange</div>
</div>
function GetSelected() {
var selected = new Array();
var tblFruits = document.getElementById("tblFruits");
var chks = tblFruits.getElementsByTagName("INPUT");
// this for loop will check checkbox current value and will hide fruits divs
for (var i = 0; i < chks.length; i++) {
if (chks[i].checked) {
selected.push(chks[i].value);
document.getElementById(chks[i].value).style.display = "block";
} else {
document.getElementById(chks[i].value).style.display = "none";
}
}
console.log(selected); // All selected fruit stored in this array will diaplyed on console
}
Here is working demo https://playcode.io/657247/
Upvotes: 0
Reputation: 13668
I would recommend avoiding situations in which you hard-code multiple conditions-- it scales very poorly. Instead, I would find a way to link each checkbox to an option and simply loop the results. In the below, we get the associated text label and use it to find the matched div by id
to show it:
function GetSelected() {
var selected = new Array();
var tblFruits = document.getElementById("tblFruits");
var chks = tblFruits.getElementsByTagName("INPUT");
// clear all previously shown options
const divs = document.querySelectorAll('.wrapper > div');
[...divs].forEach(div => {
div.style.display = 'none';
});
for (var i = 0; i < chks.length; i++) {
if (chks[i].checked) {
let value = chks[i].value;
let text = chks[i].labels[0].textContent.toLowerCase();;
selected.push(value);
document.querySelector(`#${text}`).style.display = 'block';
}
}
// do anything else you need with the checkbox array
}
#mango, #apple, #banana, #guava, #orange {
display: none;
}
<table id="tblFruits">
<tr>
<td><input id="chkMango" type="checkbox" value="1"/><label for="chkMango">Mango</label></td>
</tr>
<tr>
<td><input id="chkApple" type="checkbox" value="2"/><label for="chkApple">Apple</label></td>
</tr>
<tr>
<td><input id="chkBanana" type="checkbox" value="3"/><label for="chkBanana">Banana</label></td>
</tr>
<tr>
<td><input id="chkGuava" type="checkbox" value="4"/><label for="chkGuava">Guava</label></td>
</tr>
<tr>
<td><input id="chkOrange" type="checkbox" value="5"/><label for="chkOrange">Orange</label></td>
</tr>
</table>
<br />
<input type = "button" value = "Get" onclick = "GetSelected()" />
<p> </p>
<div class="wrapper">
<div id="mango">Mango</div>
<div id="apple">Apple</div>
<div id="banana">Banana</div>
<div id="guava">Guava</div>
<div id="orange">Orange</div>
</div>
This solution attempted to not touch/change any of the markup. It's super flimsy as is-- all you need is for the label to have a space and it falls apart. Instead, consider using data-
attributes to provide more concrete links between the two pieces of markup that can be used to connect them and make changes as need in a manner that is derived.
Upvotes: 0