So how can I only allow a user to select only one checkbox?
I know radio buttons are "ideal", but for my purpose...it's not.
I have a field where users need to select either or of the two options, but not both. The problem is that I need my users to also be able to unselect their option, and this is where radio buttons fail because once you select the group, you have to choose an option.
I will be validating the info via php, but I'd still like to restrict the users to one answer if they want to give it.
Here is a simple HTML and JavaScript solution I prefer:
//js function to allow only checking of one weekday checkbox at a time:
function checkOnlyOne(b){
var x = document.getElementsByClassName('daychecks');
var i;
for (i = 0; i < x.length; i++) {
if(x[i].value != b) x[i].checked = false;
}
}
Day of the week:
<input class="daychecks" onclick="checkOnlyOne(this.value);" type="checkbox" name="reoccur_weekday" value="Monday" />Mon
<input class="daychecks" onclick="checkOnlyOne(this.value);" type="checkbox" name="reoccur_weekday" value="Tuesday" />Tue
<input class="daychecks" onclick="checkOnlyOne(this.value);" type="checkbox" name="reoccur_weekday" value="Wednesday" />Wed
<input class="daychecks" onclick="checkOnlyOne(this.value);" type="checkbox" name="reoccur_weekday" value="Thursday" />Thu
<input class="daychecks" onclick="checkOnlyOne(this.value);" type="checkbox" name="reoccur_weekday" value="Friday" />Fri
<input class="daychecks" onclick="checkOnlyOne(this.value);" type="checkbox" name="reoccur_weekday" value="Saturday" />Sat
<input class="daychecks" onclick="checkOnlyOne(this.value);" type="checkbox" name="reoccur_weekday" value="Sunday" />Sun <br /><br />
Necromancing:
And without jQuery, for a checkbox structure like this:
<label>
<input type="checkbox" id="mytrackers_1" name="blubb_1" value="">--- Bitte auswählen ---
</label>
<label>
<input type="checkbox" id="mytrackers_2" name="blubb_2" value="7">Testtracker
</label>
<label>
<input type="checkbox" id="mytrackers_3" name="blubb_3" value="3">Kundenanfrage
</label>
<label>
<input type="checkbox" id="mytrackers_4" name="blubb_4" value="2">Anpassung
</label>
<label>
<input type="checkbox" id="mytrackers_5" name="blubb_5" value="1" checked="checked" >Fehler
</label>
<label>
<input type="checkbox" id="mytrackers_6" name="blubb_6" value="4">Bedienung
</label>
<label>
<input type="checkbox" id="mytrackers_7" name="blubb_7" value="5">Internes
</label>
<label>
<input type="checkbox" id="mytrackers_8" name="blubb_8" value="6">Änderungswunsch
</label>
you would do it like this:
/// attach an event handler, now or in the future,
/// for all elements which match childselector,
/// within the child tree of the element maching parentSelector.
function subscribeEvent(parentSelector, eventName, childSelector, eventCallback) {
if (parentSelector == null)
throw new ReferenceError("Parameter parentSelector is NULL");
if (childSelector == null)
throw new ReferenceError("Parameter childSelector is NULL");
// nodeToObserve: the node that will be observed for mutations
var nodeToObserve = parentSelector;
if (typeof (parentSelector) === 'string')
nodeToObserve = document.querySelector(parentSelector);
var eligibleChildren = nodeToObserve.querySelectorAll(childSelector);
for (var i = 0; i < eligibleChildren.length; ++i) {
eligibleChildren[i].addEventListener(eventName, eventCallback, false);
} // Next i
// https://stackoverflow.com/questions/2712136/how-do-i-make-this-loop-all-children-recursively
function allDescendants(node) {
if (node == null)
return;
for (var i = 0; i < node.childNodes.length; i++) {
var child = node.childNodes[i];
allDescendants(child);
} // Next i
// IE 11 Polyfill
if (!Element.prototype.matches)
Element.prototype.matches = Element.prototype.msMatchesSelector;
if (node.matches) {
if (node.matches(childSelector)) {
// console.log("match");
node.addEventListener(eventName, eventCallback, false);
} // End if ((<Element>node).matches(childSelector))
// else console.log("no match");
} // End if ((<Element>node).matches)
// else console.log("no matchfunction");
} // End Function allDescendants
// Callback function to execute when mutations are observed
var callback = function (mutationsList, observer) {
for (var _i = 0, mutationsList_1 = mutationsList; _i < mutationsList_1.length; _i++) {
var mutation = mutationsList_1[_i];
// console.log("mutation.type", mutation.type);
// console.log("mutation", mutation);
if (mutation.type == 'childList') {
for (var i = 0; i < mutation.addedNodes.length; ++i) {
var thisNode = mutation.addedNodes[i];
allDescendants(thisNode);
} // Next i
} // End if (mutation.type == 'childList')
// else if (mutation.type == 'attributes') { console.log('The ' + mutation.attributeName + ' attribute was modified.');
} // Next mutation
}; // End Function callback
// Options for the observer (which mutations to observe)
var config = { attributes: false, childList: true, subtree: true };
// Create an observer instance linked to the callback function
var observer = new MutationObserver(callback);
// Start observing the target node for configured mutations
observer.observe(nodeToObserve, config);
} // End Function subscribeEvent
function radioCheckbox_onClick()
{
// console.log("click", this);
let box = this;
if (box.checked)
{
let name = box.getAttribute("name");
let pos = name.lastIndexOf("_");
if (pos !== -1) name = name.substr(0, pos);
let group = 'input[type="checkbox"][name^="' + name + '"]';
// console.log(group);
let eles = document.querySelectorAll(group);
// console.log(eles);
for (let j = 0; j < eles.length; ++j)
{
eles[j].checked = false;
}
box.checked = true;
}
else
box.checked = false;
}
// https://stackoverflow.com/questions/9709209/html-select-only-one-checkbox-in-a-group
function radioCheckbox()
{
// on instead of document...
let elements = document.querySelectorAll('input[type="checkbox"]')
for (let i = 0; i < elements.length; ++i)
{
// console.log(elements[i]);
elements[i].addEventListener("click", radioCheckbox_onClick, false);
} // Next i
} // End Function radioCheckbox
function onDomReady()
{
console.log("dom ready");
subscribeEvent(document, "click",
'input[type="checkbox"]',
radioCheckbox_onClick
);
// radioCheckbox();
}
if (document.addEventListener) document.addEventListener("DOMContentLoaded", onDomReady, false);
else if (document.attachEvent) document.attachEvent("onreadystatechange", onDomReady);
else window.onload = onDomReady;
function onPageLoaded() {
console.log("page loaded");
}
if (window.addEventListener) window.addEventListener("load", onPageLoaded, false);
else if (window.attachEvent) window.attachEvent("onload", onPageLoaded);
else window.onload = onPageLoaded;
Checkbox Group
var group_=(el,callback)=>{
el.forEach((checkbox)=>{
callback(checkbox)
})
}
group_(document.getElementsByName('check'),(item)=>{
item.onclick=(e)=>{
group_(document.getElementsByName('check'),(item)=>{
item.checked=false;
})
e.target.checked=true;
}
})
_x000D_
<input type="checkbox" name="check" >
<input type="checkbox" name="check" >
<input type="checkbox" name="check" >
<input type="checkbox" name="check">
_x000D_
checkbox simple without loop
var last;
document.addEventListener('input',(e)=>{
if(e.target.getAttribute('name')=="myRadios"){
if(last)
last.checked=false;
}
e.target.checked=true;
last=e.target;
})
_x000D_
<input type="checkbox" name="myRadios" value="1" /> 1
<input type="checkbox" name="myRadios" value="2" /> 2
_x000D_
Group By Single Div
var group_=(el,callback)=>{
el.forEach((checkbox)=>{
callback(checkbox)
})
}
var group_el=document.querySelectorAll("*[data-name] > input")
group_(group_el,(item)=>{
item.onclick=(e)=>{
group_(group_el,(item)=>{
item.checked=false;
})
e.target.checked=true;
}
})
_x000D_
<div data-name="check">
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
</div>
_x000D_
css single group div
var last;
document.addEventListener('input',(e)=>{
var closest=e.target.closest("*[data-name='check']");
console.log(closest)
if(e.target.closest("*[data-name]")){
if(last)
last.checked=false;
}
e.target.checked=true;
last=e.target;
})
_x000D_
<div data-name="check">
<input type="checkbox" value="1" /> 1
<input type="checkbox" value="2" /> 2
</div>
_x000D_
var last;
document.addEventListener('input',(e)=>{
var closest=e.target.closest("*[data-name='check']");
if(e.target.closest("*[data-name]")){
if(last)
last.checked=false;
}
if(e.target!==last)
last=e.target;
else
last=undefined;
})
_x000D_
<div data-name="check">
<input type="checkbox" value="1" /> 1
<input type="checkbox" value="2" /> 2
</div>
_x000D_
Radio buttons are ideal. You just need a third "neither" option that is select by default.
May this code helps you.
$(document).ready(function(){_x000D_
$('.slectOne').on('change', function() {_x000D_
$('.slectOne').not(this).prop('checked', false);_x000D_
$('#result').html($(this).data( "id" ));_x000D_
if($(this).is(":checked"))_x000D_
$('#result').html($(this).data( "id" ));_x000D_
else_x000D_
$('#result').html('Empty...!');_x000D_
});_x000D_
});
_x000D_
<!DOCTYPE html>_x000D_
<html>_x000D_
<head>_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>_x000D_
_x000D_
</head>_x000D_
<body>_x000D_
<input type="checkbox" class="slectOne" data-id="1 selected"/>_x000D_
<input type="checkbox" class="slectOne" data-id="2 selected"/>_x000D_
<input type="checkbox" class="slectOne" data-id="3 selected"/>_x000D_
<input type="checkbox" class="slectOne" data-id="4 selected"/>_x000D_
<input type="checkbox" class="slectOne" data-id="5 selected"/>_x000D_
<input type="checkbox" class="slectOne" data-id="6 selected"/>_x000D_
<input type="checkbox" class="slectOne" data-id="7 selected"/>_x000D_
<input type="checkbox" class="slectOne" data-id="8 selected"/>_x000D_
<input type="checkbox" class="slectOne" data-id="9 selected"/>_x000D_
<input type="checkbox" class="slectOne" data-id="10 selected"/>_x000D_
<span id="result"></span>_x000D_
</body>_x000D_
</html>
_x000D_
Working link Click here
Building up on billyonecan's answer, you can use the following code if you need that snippet for more than one checkbox (assuming they have different names).
$('input.one').on('change', function() {
var name = $(this).attr('name');
$('input[name='+name+'].one').not(this).prop('checked', false);
});
You'd want to bind a change()
handler so that the event will fire when the state of a checkbox changes. Then, just deselect all checkboxes apart from the one which triggered the handler:
$('input[type="checkbox"]').on('change', function() {
$('input[type="checkbox"]').not(this).prop('checked', false);
});
As for grouping, if your checkbox "groups" were all siblings:
<div>
<input type="checkbox" />
<input type="checkbox" />
<input type="checkbox" />
</div>
<div>
<input type="checkbox" />
<input type="checkbox" />
<input type="checkbox" />
</div>
<div>
<input type="checkbox" />
<input type="checkbox" />
<input type="checkbox" />
</div>
You could do this:
$('input[type="checkbox"]').on('change', function() {
$(this).siblings('input[type="checkbox"]').prop('checked', false);
});
If your checkboxes are grouped by another attribute, such as name
:
<input type="checkbox" name="group1[]" />
<input type="checkbox" name="group1[]" />
<input type="checkbox" name="group1[]" />
<input type="checkbox" name="group2[]" />
<input type="checkbox" name="group2[]" />
<input type="checkbox" name="group2[]" />
<input type="checkbox" name="group3[]" />
<input type="checkbox" name="group3[]" />
<input type="checkbox" name="group3[]" />
You could do this:
$('input[type="checkbox"]').on('change', function() {
$('input[name="' + this.name + '"]').not(this).prop('checked', false);
});
My version: use data attributes and Vanilla JavaScript
<div class="test-checkbox">
Group One: <label>
<input type="checkbox" data-limit="only-one-in-a-group" name="groupOne" value="Eat" />Eat</label>
<label>
<input type="checkbox" data-limit="only-one-in-a-group" name="groupOne" value="Sleep" />Sleep</label>
<label>
<input type="checkbox" data-limit="only-one-in-a-group" name="groupOne" value="Play" />Play</label>
<br />
Group Two: <label>
<input type="checkbox" data-limit="only-one-in-a-group" name="groupTwo" value="Fat" />Fat</label>
<label>
<input type="checkbox" data-limit="only-one-in-a-group" name="groupTwo" value="Comfort" />Comfort</label>
<label>
<input type="checkbox" data-limit="only-one-in-a-group" name="groupTwo" value="Happy" />Happy</label>
</div>
<script>
let cbxes = document.querySelectorAll('input[type="checkbox"][data-limit="only-one-in-a-group"]');
[...cbxes].forEach((cbx) => {
cbx.addEventListener('change', (e) => {
if (e.target.checked)
uncheckOthers(e.target);
});
});
function uncheckOthers (clicked) {
let name = clicked.getAttribute('name');
// find others in same group, uncheck them
[...cbxes].forEach((other) => {
if (other != clicked && other.getAttribute('name') == name)
other.checked = false;
});
}
</script>
There are already a few answers to this based on pure JS but none of them are quite as concise as I would like them to be.
Here is my solution based on using name tags (as with radio buttons) and a few lines of javascript.
function onlyOne(checkbox) {_x000D_
var checkboxes = document.getElementsByName('check')_x000D_
checkboxes.forEach((item) => {_x000D_
if (item !== checkbox) item.checked = false_x000D_
})_x000D_
}
_x000D_
<input type="checkbox" name="check" onclick="onlyOne(this)">_x000D_
<input type="checkbox" name="check" onclick="onlyOne(this)">_x000D_
<input type="checkbox" name="check" onclick="onlyOne(this)">_x000D_
<input type="checkbox" name="check" onclick="onlyOne(this)">
_x000D_
While JS is probably the way to go, it could be done with HTML and CSS only.
Here you have a fake radio button which is really a label for a real hidden radio button. By doing that, you get exactly the effect you need.
<style>
#uncheck>input { display: none }
input:checked + label { display: none }
input:not(:checked) + label + label{ display: none }
</style>
<div id='uncheck'>
<input type="radio" name='food' id="box1" />
Pizza
<label for='box1'>◎</label>
<label for='box0'>◉</label>
<input type="radio" name='food' id="box2" />
Ice cream
<label for='box2'>◎</label>
<label for='box0'>◉</label>
<input type="radio" name='food' id="box0" checked />
</div>
See it here: https://jsfiddle.net/tn70yxL8/2/
Now, that assumes you need non-selectable labels.
If you were willing to include the labels, you can technically avoid repeating the "uncheck" label by changing its text in CSS, see here: https://jsfiddle.net/7tdb6quy/2/
Example With AngularJs
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>_x000D_
<!DOCTYPE html>_x000D_
<html>_x000D_
_x000D_
<head>_x000D_
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>_x000D_
<script>_x000D_
angular.module('app', []).controller('appc', ['$scope',_x000D_
function($scope) {_x000D_
$scope.selected = 'other';_x000D_
}_x000D_
]);_x000D_
</script>_x000D_
</head>_x000D_
_x000D_
<body ng-app="app" ng-controller="appc">_x000D_
<label>SELECTED: {{selected}}</label>_x000D_
<div>_x000D_
<input type="checkbox" ng-checked="selected=='male'" ng-true-value="'male'" ng-model="selected">Male_x000D_
<br>_x000D_
<input type="checkbox" ng-checked="selected=='female'" ng-true-value="'female'" ng-model="selected">Female_x000D_
<br>_x000D_
<input type="checkbox" ng-checked="selected=='other'" ng-true-value="'other'" ng-model="selected">Other_x000D_
</div>_x000D_
_x000D_
_x000D_
_x000D_
</body>_x000D_
_x000D_
</html>
_x000D_
$("#myform input:checkbox").change(function() {
$("#myform input:checkbox").attr("checked", false);
$(this).attr("checked", true);
});
This should work for any number of checkboxes in the form. If you have others that aren't part of the group, set up the selectors the applicable inputs.
If someone need a solution without an external javascript libraries you could use this example. A group of checkboxes allowing 0..1 values. You may click on the checkbox component or associated label text.
<input id="mygroup1" name="mygroup" type="checkbox" value="1" onclick="toggleRadioCheckbox(this)" /> <label for="mygroup1">Yes</label>
<input id="mygroup0" name="mygroup" type="checkbox" value="0" onclick="toggleRadioCheckbox(this)" /> <label for="mygroup0">No</label>
- - - - - - - -
function toggleRadioCheckbox(sender) {
// RadioCheckbox: 0..1 enabled in a group
if (!sender.checked) return;
var fields = document.getElementsByName(sender.name);
for(var idx=0; idx<fields.length; idx++) {
var field = fields[idx];
if (field.checked && field!=sender)
field.checked=false;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>_x000D_
<!DOCTYPE html>_x000D_
<html>_x000D_
_x000D_
<head>_x000D_
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>_x000D_
<script>_x000D_
angular.module('app', []).controller('appc', ['$scope',_x000D_
function($scope) {_x000D_
$scope.selected = 'male';_x000D_
}_x000D_
]);_x000D_
</script>_x000D_
</head>_x000D_
_x000D_
<body ng-app="app" ng-controller="appc">_x000D_
<label>SELECTED: {{selected}}</label>_x000D_
<div>_x000D_
<input type="checkbox" ng-checked="selected=='male'" ng-true-value="'male'" ng-model="selected">Male_x000D_
<br>_x000D_
<input type="checkbox" ng-checked="selected=='female'" ng-true-value="'female'" ng-model="selected">Female_x000D_
<br>_x000D_
<input type="checkbox" ng-checked="selected=='other'" ng-true-value="'other'" ng-model="selected">Other_x000D_
</div>_x000D_
</body>_x000D_
</html>
_x000D_
With plain old javascript.
<html>
<head>
</head>
<body>
<input type="checkbox" name="group1[]" id="groupname1" onClick="toggle(1,'groupname')"/>
<input type="checkbox" name="group1[]" id="groupname2" onClick="toggle(2,'groupname')" />
<input type="checkbox" name="group1[]" id="groupname3" onClick="toggle(3,'groupname')" />
<input type="checkbox" name="group2[]" id="diffGroupname1" onClick="toggle(1,'diffGroupname')"/>
<input type="checkbox" name="group2[]" id="diffGroupname2" onClick="toggle(2,'diffGroupname')" />
<input type="checkbox" name="group2[]" id="diffGroupname3" onClick="toggle(3,'diffGroupname')" />
<script>
function toggle(which,group){
var counter=1;
var checkbox=document.getElementById(group+counter);
while(checkbox){
if(counter==which){
}else{
checkbox.checked=false;
}
counter++;
checkbox=document.getElementById(group+counter);
}
}
</script>
</body>
</html>
edit: also possible
<html>
<head>
</head>
<body>
<input type="checkbox" name="group1[]" class="groupname" onClick="toggle(this,'groupname')"/>
<input type="checkbox" name="group1[]" class="groupname" onClick="toggle(this,'groupname')" />
<input type="checkbox" name="group1[]" class="groupname" onClick="toggle(this,'groupname')" />
<input type="checkbox" name="group2[]" class="diffGroupname" onClick="toggle(this,'diffGroupname')"/>
<input type="checkbox" name="group2[]" class="diffGroupname" onClick="toggle(this,'diffGroupname')" />
<input type="checkbox" name="group2[]" class="diffGroupname" onClick="toggle(this,'diffGroupname')" />
<script>
function toggle(which,theClass){
var checkbox=document.getElementsByClassName(theClass);
for(var i=0;i<checkbox.length;i++){
if(checkbox[i]==which){
}else{
checkbox[i].checked=false;
}
}
}
</script>
</body>
</html>
The Code snippet below demonstrates a simple approach for selecting only one checkbox in a group.
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<body>
<h3>Demonstration of Checkbox Toggle</h3>
<p>
<span><b>Letters:</b></span>
A<input type="checkbox" name="A" >
B<input type="checkbox" name="B" >
C<input type="checkbox" name="C" >
D<input type="checkbox" name="D" >
</p>
<p>
<span><b>Numbers:</b></span>
1<input type="checkbox" name="1" >
2<input type="checkbox" name="2" >
3<input type="checkbox" name="3" >
</p>
<p>
<span><b>Birds:</b></span>
Scarlet Ibis<input type="checkbox" name="Scarlet Ibis" >
Cocrico <input type="checkbox" name="Cocrico" >
hummingbird <input type="checkbox" name="hummingbird" >
</p>
</body>
<script>
$(function()
{
function toggle(choices,name)
{
if(choices.includes(name))
{
for( i=0;i<choices.length;i++)
{
if(name !=choices[i])
$('input[name="' + choices[i] + '"]').not(this).prop('checked', false);
}
}
}
$('input[type="checkbox"]').on('change', function()
{
var letters = ["A","B","C","D"];
var numbers = ["1", "2", "3"];
var birds = ["Scarlet Ibis", "Cocrico", "hummingbird"];
toggle(letters,this.name);
toggle(numbers,this.name);
toggle(birds,this.name);
});
});
</script>
</html>
_x000D_
//Here is a solution using JQuery
<input type = "checkbox" class="a"/>one
<input type = "checkbox" class="a"/>two
<input type = "checkbox" class="a"/>three
<script>
$('.a').on('change', function() {
$('.a').not(this).prop('checked',false);
});
</script>
Source: Stackoverflow.com