select only one checkbox in a group not working 100% - javascript

I'm trying to make it where the user can only select 1 checkbox at a time on a page.
Here's my code so far:
function onlyOne(checkbox) {
var checkboxes = document.getElementsByName('active', 'inactive',
'showall')
checkboxes.forEach((item) => {
if (item !== checkbox) item.checked = false
})
}
<strong>Active</strong>
<input type="checkbox" name="active" value="Yes" onclick="onlyOne(this)">
<strong>Inactive</strong>
<input type="checkbox" name="inactive" value="Yes" onclick="onlyOne(this)">
<strong>Show All</strong>
<input type="checkbox" name="showall" value="Yes" onclick="onlyOne(this)">
What keeps happening is it will work sometimes and sometimes they can select more than 1 checkbox. What do I need to tweak to get it working all the time.

HTML DOM getElementsByName() Method Gets all elements with the specified name
So In your code It's getting only the first name active ;
as a result the length of the list of checkboxs is 1 this is why your code doesn't work correctly.
If you want to make sure that what i am saying is true change your code to this and your logic will work just fine:
function onlyOne(checkbox) {
var checkboxes = document.getElementsByName('active');
checkboxes.forEach((item) => {
if (item !== checkbox)
item.checked = false;
})
}
<strong>Active</strong>
<input type="checkbox" name="active" value="Yes" onclick="onlyOne(this)">
<strong>Inactive</strong>
<input type="checkbox" name="active" value="Yes"
onclick="onlyOne(this)">
<strong>Show All</strong>
<input type="checkbox" name="active" value="Yes" onclick="onlyOne(this)">
As the others recommended use the radio buttons it's much easier I just wanted to clear this for you.
EDIT :
If you still want to use checkbox use querySelectorAll instead of your getElementsByName
var checkboxes = document.querySelectorAll('[name="active"], [name="inactive"], [name="showall"]');

You can use radio buttons to do this, it needs no JavaScript and is supported by pretty much everything, Internet Explorer included. They can be used like so:
<div>
<strong>Active</strong>
<input type="radio" name="select" id="active" checked> <!-- Checked means that it is initially selected -->
</div>
<div>
<strong>Inactive</strong>
<input type="radio" name="select" id="inactive">
</div>
<div>
<strong>Show All</strong>
<input type="radio" name="select" id="showall">
</div>
Notice how because they are all technically the same input, they all have to have the same name, but you can instead use IDs to tell between them if you really need to.

Using radio buttons would be the preferred choice. But if you do want to use checkboxes, you can use the following approach.
<strong>Active</strong>
<input type="checkbox" name="chkbox" value="Yes" onclick="onlyOne(this)">
<strong>Inactive</strong>
<input type="checkbox" name="chkbox" value="Yes"
onclick="onlyOne(this)">
<strong>Show All</strong>
<input type="checkbox" name="chkbox" value="Yes" onclick="onlyOne(this)">
<script>
function onlyOne(checkbox) {
var checkboxes = document.getElementsByName('chkbox')
checkboxes.forEach((item) => {
item.checked = false
})
checkbox.checked = true
}
</script>
Note that the name attribute for all the input fields are the same.

getElementsByName() only takes one argument. The other arguments you're giving are being ignores, so you're only processing the active checkbox.
Give all your checkboxes the same class, and use getElementsByClassName() instead.
function onlyOne(checkbox) {
var checkboxes = Array.from(document.getElementsByClassName('radio'))
checkboxes.forEach((item) => {
if (item !== checkbox) item.checked = false
})
}
<strong>Active</strong>
<input type="checkbox" name="active" value="Yes" class="radio" onclick="onlyOne(this)">
<strong>Inactive</strong>
<input type="checkbox" name="inactive" value="Yes" class="radio" onclick="onlyOne(this)">
<strong>Show All</strong>
<input type="checkbox" name="showall" value="Yes" class="radio" onclick="onlyOne(this)">

You are using getElementsByName incorrectly as you can only pass one name to it and it is not an Array so you can't forEach it.
You can use querySelectorAll to query by multiple names and use forEach from the Array prototype.
function onlyOne(checkbox) {
var checkboxes = document.querySelectorAll('[name=active],[name=inactive],[name=showall]')
Array.prototype.forEach.call(checkboxes, (item,i) => {
if (item !== checkbox) item.checked = false
})
}
<strong>Active</strong>
<input type="checkbox" name="active" value="Yes" onclick="onlyOne(this)">
<strong>Inactive</strong>
<input type="checkbox" name="inactive" value="Yes"
onclick="onlyOne(this)">
<strong>Show All</strong>
<input type="checkbox" name="showall" value="Yes" onclick="onlyOne(this)">
While using a radio button control might be the way to go, that just really a comment and not an answer.

Related

Verify all radio groups have a value checked using a generic selector

How to Verify all radio groups have at least 1 value selected using a generic selector and the .each() function.
All the examples I find require the id or name of the single radio options to be used not the group.
Try this:
const radios = {};
$('input[type="radio"]').each((i, e) => {
let $radio = $(e);
if ($radio.is(':checked')) {
radios[$radio.attr('name')] = $radio.val();
}
});
console.log(radios);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<input type="radio" value="1" name="ri1">
<input type="radio" value="2" name="ri1" checked="checked">
<input type="radio" value="3" name="ri1">
<input type="radio" value="1" name="ri2">
<input type="radio" value="2" name="ri2">
<input type="radio" value="3" name="ri2" checked="checked">

Unchecking all checkboxes with the escape key

I'm trying to enable the user to uncheck all checkboxes with the escape key.
I found this code snippet that does the job, but by clicking a button.
<form>
<input type="checkbox" name="checkBox" >one<br>
<input type="checkbox" name="checkBox" >two<br>
<input type="checkbox" name="checkBox" >three<br>
<input type="checkbox" name="checkBox" >four<br>
<input type=button name="CheckAll" value="Select_All" onClick="check(true,10)">
<input type=button name="UnCheckAll" value="UnCheck All Boxes" onClick="check(false,10)">
</form>
function check(checked,total_boxes){
for ( i=0 ; i < total_boxes ; i++ ){
if (checked){
document.forms[0].checkBox[i].checked=true;
}else{
document.forms[0].checkBox[i].checked=false;
}
}
}
document.addEventListener('keydown', (event) => {
if (event.key === 'Escape') {
// uncheck all checkboxes
}
});
The code doesn't work on checkboxes that are not in a tag.
Sometimes I use checkboxes for CSS only on-click events, which are not inside of a form.
The use case here is for CSS only menu pop-ups and drop-downs.
I'm trying to make them accessible by allowing the user to close with the escape key.
Sure, it's not CSS only any more, but I need to improve accessibility.
This should do it:
function allCB(checked){
document.querySelectorAll("input[type=checkbox]").forEach(cb=>cb.checked=checked)
}
document.addEventListener('keydown',_=>event.key === 'Escape' && allCB(false));
document.querySelector("form").addEventListener('click',ev=>ev.target.type=="button" && allCB(ev.target.name=="CheckAll"));
<form>
<label><input type="checkbox" name="checkBox">one</label><br>
<label><input type="checkbox" name="checkBox">two</label><br>
<label><input type="checkbox" name="checkBox">three</label><br>
<label><input type="checkbox" name="checkBox">four</label><br>
<input type=button name="CheckAll" value="Select_All">
<input type=button name="UnCheckAll" value="UnCheck All Boxes">
</form>

Javascript radio group by button

How to display an alert msg when all radio button checked to no? I only know check radio by individual only.
//I only know this method
$('#attraction1').change( function(){
if ($(this).is(':checked')) {
alert('Yes');
}
});
Attraction :
<input type="radio" id="attraction1" name="attraction" value="y" checked/> Yes
<input type="radio" id="attraction2" name="attraction" value="n" /> No
<br>
Individual Attraction :
<input type="radio" id="individual1" name="individual" value="y" checked/> Yes
<input type="radio" id="individual2" name="individual" value="n" /> No
<br>
Plan Board:
<input type="radio" id="planBoard1" name="planBoard" value="y" checked/> Yes
<input type="radio" id="planBoard2" name="planBoard" value="n" /> No
In this case you should check something like this
$('#some_button').click( function(){
if ($('input[type="radio"][value="n"]:checked').length == 3) {
alert('Yes');
}
});
You can use a common class for all radio button with no value and a javascript array every method.
This line const radioNames = [...document.getElementsByClassName('no')]; will get all the radio button with no value ... is spread operator and will convert collection so that array method can be used on that collection.
This line item.addEventListener('change', checkIfAllNo) will attach event change to radio button with value no so that it checks the value for all other radio button
Array method every will return true if all the value in that array satisfies the condition.
So in this line radioNames.every(item => {return item.checked;}); if all the radio button with no value is checked then isAllFalse will be true & the alert will be triggered.
const radioNames = [...document.getElementsByClassName('no')];
function checkIfAllNo() {
const isAllFalse = radioNames.every(item => {
return item.checked;
});
if (isAllFalse) {
alert('All False')
}
}
radioNames.forEach((item) => {
item.addEventListener('change', checkIfAllNo)
})
<input type="radio" id="attraction1" name="attraction" value="y" checked/> Yes
<input type="radio" class="no" id="attraction2" name="attraction" value="n" /> No
<br> Individual Attraction :
<input type="radio" id="individual1" name="individual" value="y" checked/> Yes
<input type="radio" id="individual2" class="no" name="individual" value="n" /> No
<br> Plan Board:
<input type="radio" id="planBoard1" name="planBoard" value="y" checked/> Yes
<input type="radio" id="planBoard2" class="no" name="planBoard" value="n" /> No
In case you have an indeterminate number of inputs you can collect the values for every group and then check if all values match
$("input[type='radio']").change(function() {
// Extract all the radio group names
names = $.unique($('input[type="radio"]').map((v, e) => $(e).attr('name')))
// Collect the value for each group.
// Account for groups that are not selected yet
vals = $.map(names, function(name) {
return $(`input:radio[name="${name}"]:checked`).val() || 'undefined';
})
// Check if collected values match 'n'
console.log(vals.every(v => v == 'n'))
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Attraction :
<input type="radio" id="attraction1" name="attraction" value="y" /> Yes
<input type="radio" id="attraction2" name="attraction" value="n" /> No
<br> Individual Attraction :
<input type="radio" id="individual1" name="individual" value="y" /> Yes
<input type="radio" id="individual2" name="individual" value="n" checked/> No
<br> Plan Board:
<input type="radio" id="planBoard1" name="planBoard" value="y" checked/> Yes
<input type="radio" id="planBoard2" name="planBoard" value="n" /> No
#ForeverTwoWheels
Please try this code,To Javascript radio group by button
<!DOCTYPE html>
<html>
<head>
<title>JavaScript Radio Buttons</title>
</head>
<body>
<form>
<input type="radio" name="choice" value="yes"> Yes
<input type="radio" name="choice" value="no"> No
<input type="button" id="btn" value="Show Selected Value">
</form>
<script>
const btn = document.querySelector('#btn');
// handle click button
btn.onclick = function () {
const rbs = document.querySelectorAll('input[name="choice"]');
let selectedValue;
for (const rb of rbs) {
if (rb.checked) {
selectedValue = rb.value;
break;
}
}
alert(selectedValue);
};
</script>
</body>
</html>
I hope this information will be usefull for you.
Thank you.

As for all the tags input with the specified attribute to set, for example, attribute checked = false?

Put tags input type = "radio" with its attribute data-group:
<input type="radio" id="id1" data-group="group1">
<input type="radio" id="id2" data-group="group1"><br>
<input type="radio" id="id3" data-group="group2">
<input type="radio" id="id4" data-group="group2"><br>
How at all elements of input type="radio", which is data-group "group1", set the checked=false?
You can use the attribute selector:
$('input[type="radio"][data-group="group1"]').prop('checked', false);
Or filter():
$('input[type="radio"]').filter(function() {
return $(this).data('group') == 'group1';
}).prop('checked', false);
The best way to group radio buttons is to use the name attribute; the browser will then group them together for you, unchecking others when you check another member of the same group. That's the purpose of input[type=radio]:
<input type="radio" id="id1" name="group1">
<input type="radio" id="id2" name="group1"><br>
<input type="radio" id="id3" name="group2">
<input type="radio" id="id4" name="group2"><br>
And if you wanted to make all of the name="group1" ones unchecked, then:
$("input[type=radio][name=group1]").prop("checked", false);
But if you want to use your current structure, and you're asking how to set them all unchecked, then you can use an attribute selector:
$("input[type=radio][data-group=group1]").prop("checked", false);

How to find the value of a radio button with pure javascript?

<input checked=checked type="radio" name="colors" value="red" />Red
<input type="radio" name="colors" value="green" />Green
<input type="radio" name="colors" value="blue" />Blue
Given the above, I set the red button to be selected by default (so I give it the checked=checked attribute. With this, if I ever call .checked on that input element, it will always return true, even if another option is selected.
In plain javascript (no jQuery), how can you get the actual selected option?
Try this:
var options = document.getElementsByName("colors");
if (options) {
for (var i = 0; i < options.length; i++) {
if (options[i].checked){
alert(options[i].value);
}
}
}
Would be so much easier with jQuery though... just saying.
I believe you will find it in the document.all collection:
var selectedColor = document.all["colors"];
plain javasript:
document.querySelector('input[name=colors]:checked').value;
you can try like this .....
This is example
<form name="frmRadio" method="post">
<input name="choice" value="1" type="radio" />1
<input name="choice" value="2" type="radio" />2
<input name="choice" value="3" type="radio" />3
<input name="choice" value="4" type="radio" />4
</form>
function to get the selected value
<script language="JavaScript">
function getRadioValue() {
for (index=0; index < document.frmRadio.choice.length; index++) {
if (document.frmRadio.choice[index].checked) {
var radioValue = document.frmRadio.choice[index].value;
break;
}
}
}
</script>
Well, they all have the same name. So naturally at least one of them has to be selected. Give them different ID's and try again.

Categories