37

I need to manipulate the behavior of the check boxes with javascript. They should basically behave like radio buttons (only one selectable at a time, plus unselect any previous selections).

The problem is that I can't use plain radio buttons in first place, because the name attribute for each radio button would be different.

I know its not the ultimate and shiniest solutions to make an apple look like a pear, and w3c wouldn't give me their thumbs for it, but it would be a better solution right now than to change the core php logic of the entire cms structure ;-)

Any help is much appreciated!

Brad Larson
  • 170,088
  • 45
  • 397
  • 571
Christian
  • 681
  • 1
  • 6
  • 15
  • 3
    Using jQuery: http://stackoverflow.com/questions/881166/jquery-checkboxes-like-radiobuttons – leek Apr 30 '11 at 05:57
  • Are you using a framework such (e.g. jQuery) or not. I would not tell you to add jQuery or any other framework to your project for a simple task such as this one, unless you're using one. – Salman A Apr 30 '11 at 06:33

12 Answers12

92

HTML :

<label><input type="checkbox" name="cb1" class="chb" /> CheckBox1</label>
<label><input type="checkbox" name="cb2" class="chb" /> CheckBox2</label>
<label><input type="checkbox" name="cb3" class="chb" /> CheckBox3</label>
<label><input type="checkbox" name="cb4" class="chb" /> CheckBox4</label>

jQuery :

$(".chb").change(function() {
    $(".chb").prop('checked', false);
    $(this).prop('checked', true);
});

if you want user can unchecked selected item :

$(".chb").change(function() {
    $(".chb").not(this).prop('checked', false);
});

Demo :

http://jsfiddle.net/44Zfv/724/

DJafari
  • 12,955
  • 8
  • 43
  • 65
  • 1
    nice fiddle, + if you want to uncheck the checkbox again (this code is almost perfect except not allowing unchecking all) add this: if($(this).attr('checked')) – kubilay Sep 17 '12 at 19:02
  • 4
    Note that .attr is no longer working, use .prop("checked") instead for newer versions of jQuery – user871784 May 30 '13 at 09:45
  • 3
    can be simplified to `$(".chb").change(function()`, rather than `$(".chb").each(function(){ $(this).change(function()`, but nice. – Mike Campbell Sep 11 '13 at 09:37
  • @D.A.V.O.O.D 5 years on.. But the code doesn't work now - can someone update it? thanks. – Ben Feb 16 '16 at 11:51
  • Wow thanks for answering back... Just checked again - it's not working for me...? The checkboxes are working like regular checkboxes - not radios... You sure it's working for you?? I have since found another solution... Thanks – Ben Feb 16 '16 at 19:27
  • @Ben you say right, jquery file not loading in demo, i updated demo, you can see in updated answer ! thanks for your report – DJafari Feb 17 '16 at 11:27
  • @kubilay, what did you mean by `add this: if($(this).attr('checked'))`? Where should it be added? – Green May 02 '16 at 02:53
  • This works great, I use these checkboxes to pass the value as url parameter. As soon as I click through the boxes, the last two values are always passed as url parameter, not the very last only. Any idea, why? – Robin Alexander Dec 05 '16 at 12:43
  • Fiddle which allows unchecking of a box. I used it for filters http://jsfiddle.net/1hm7Lcf8/ – Grzegorz Dec 03 '20 at 10:05
6

This is a better option as it allows unchecking also:

$(".cb").change(function () {
    $(".cb").not(this).prop('checked', false);
});
user2352497
  • 85
  • 1
  • 8
Vaibhav Garg
  • 3,630
  • 3
  • 33
  • 55
6

There are many ways to do this. This is a clickhandler (plain js) for a div containing a number of checkboxes:

function cbclick(e){
   e = e || event;
   var cb = e.srcElement || e.target;
   if (cb.type !== 'checkbox') {return true;}
   var cbxs = document.getElementById('radiocb')
               .getElementsByTagName('input'), 
       i    = cbxs.length;
    while(i--) {
        if (cbxs[i].type 
             && cbxs[i].type == 'checkbox' 
             && cbxs[i].id !== cb.id) {
          cbxs[i].checked = false;
        }
    }
}

Here's a working example.

KooiInc
  • 119,216
  • 31
  • 141
  • 177
5

I kept it simple...

<html>
<body>

<script>
function chbx(obj)
{
var that = obj;
   if(document.getElementById(that.id).checked == true) {
      document.getElementById('id1').checked = false;
      document.getElementById('id2').checked = false;
      document.getElementById('id3').checked = false;
      document.getElementById(that.id).checked = true;
   }
}
</script>

<form action="your action" method="post">

<Input id='id1' type='Checkbox' Name ='name1' value ="S" onclick="chbx(this)"><br />
<Input id='id2' type='Checkbox' Name ='name2' value ="S" onclick="chbx(this)"><br />
<Input id='id3' type='Checkbox' Name ='name3' value ="S" onclick="chbx(this)"><br />

<input type="submit" value="Submit" />
</form>

</body>
</html>
4

Just in case it helps someone else

I was having the same situation where my client needed to have a checkbox behaving like a radio button. But to me it was meaningless to use a checkbox and make it act like radio button and it was very complex for me as I was using so many checkboxes in a GridView Control.

My Solution:
So, I styled a radio button look like a checkbox and took the help of grouping of radio buttons.

Jamshaid K.
  • 3,555
  • 1
  • 27
  • 42
  • This [SO post](https://stackoverflow.com/questions/279421/can-you-style-an-html-radio-button-to-look-like-a-checkbox) should be relevant to your answer – Ken Lee Apr 08 '23 at 02:11
4

@DJafari's answer doesn't let unchecking the checkbox. So I've updated it like this:

$(".chb").change(function(e) {

 //Getting status before unchecking all
  var status = $(this).prop("checked");

  $(".chb").prop('checked', false);
  $(this).prop('checked', true);

 //false means checkbox was checked and became unchecked on change event, so let it stay unchecked
  if (status === false) {
    $(this).prop('checked', false);
  }

});

https://jsfiddle.net/mapetek/nLtb0q1e/4/

mapetek
  • 141
  • 4
1

You could give the group of checkboxes you need to behave like this a common class, then use the class to attach the following event handler:

function clickReset ()
{
    var isChecked = false,
        clicked = $(this),
        set = $('.' + clicked.attr ('class') + ':checked').not (clicked);

    if (isChecked = clicked.attr ('checked'))
    {
        set.attr ('checked', false);
    }
    return true;
}

$(function ()
{
    $('.test').click (clickReset);
});

Note: This is pretty me just shooting from the hip, I've not tested this and it might need tweaking to work.

I would advise that you do look into finding a way of doing this with radio buttons if you can, as radios are the proper tool for the job. Users expect checkboxes to behave like checkboxes, not radios, and if they turn javascript off they can force through input into the server side script that you weren't expecting.

EDIT: Fixed function so that uncheck works properly and added a JS Fiddle link.

http://jsfiddle.net/j53gd/1/

Brian Rogers
  • 125,747
  • 31
  • 299
  • 300
GordonM
  • 31,179
  • 15
  • 87
  • 129
0

In Simple JS. Enjoy !

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
        function onChoiceChange(obj) {
            // Get Objects
            var that=obj,
                triggerChoice = document.getElementById(that.id),
                domChoice1 = document.getElementById("Choice1"),
                domChoice2 = document.getElementById("Choice2");
            // Apply
            if (triggerChoice.checked && triggerChoice.id === "Choice1") 
                domChoice2.checked=false;
            if (triggerChoice.checked && triggerChoice.id === "Choice2") 
                domChoice1.checked=false;
            // Logout
            var log = document.getElementById("message");
            log.innerHTML += "<br>"+ (domChoice1.checked ? "1" : "0") + ":" + (domChoice2.checked ? "1" : "0");
            // Return !
            return that.checked;
        }
    </script>
</head>
<body>
    <h1 id="title">Title</h1>
    <label><input type="checkbox" onclick="onChoiceChange(this)" id="Choice1" />Choice #1</label> 
    <label><input type="checkbox" onclick="onChoiceChange(this)" id="Choice2" />Choice #2</label>
    <hr>
    <div id="message"></div>
</body>
</html>
vincedgy
  • 395
  • 4
  • 6
0

try this

<form id="form" action="#">
            <input name="checkbox1" type="checkbox" />
            <input name="checkbox2" type="checkbox" />
            <input name="checkbox3" type="checkbox" />
            <input name="checkbox4" type="checkbox" />
            <input name="checkbox5" type="checkbox" />
            <input name="checkbox6" type="checkbox" />
            <input name="checkbox7" type="checkbox" />
            <input name="checkbox8" type="checkbox" />
            <input name="checkbox9" type="checkbox" />
            <input name="checkbox10" type="checkbox" />
            <input type="submit" name="submit" value="submit"/>
        </form>

and this is the javascript

(function () {
    function checkLikeRadio(tag) {
        var form = document.getElementById(tag);//selecting the form ID 
        var checkboxList = form.getElementsByTagName("input");//selecting all checkbox of that form who will behave like radio button
        for (var i = 0; i < checkboxList.length; i++) {//loop thorough every checkbox and set there value false. 
            if (checkboxList[i].type == "checkbox") {
                checkboxList[i].checked = false;
            }
            checkboxList[i].onclick = function () {
                checkLikeRadio(tag);//recursively calling the same function again to uncheck all checkbox
                checkBoxName(this);// passing the location of selected checkbox to another function. 
            };
        }
    }

    function checkBoxName(id) {
        return id.checked = true;// selecting the selected checkbox and maiking its value true; 
    }
    window.onload = function () {
        checkLikeRadio("form");
    };
})();
mitul
  • 1
  • 1
0

I like D.A.V.O.O.D's Answer to this question, but it relies on classes on the checkbox, which should not be needed.

As checkboxes tend to be related in that they will have the same (field) name, or a name which make them part of an array, then using that to decide which other checkboxes to untick would be a better solution.

$(document)
  .on('change','input[type="checkbox"]',function(e){
    var $t = $(this);
    var $form = $t.closest('form');
    var name = $t.attr('name');
    var selector = 'input[type="checkbox"]';
    var m = (new RegExp('^(.+)\\[([^\\]]+)\\]$')).exec( name );
    if( m ){
      selector += '[name^="'+m[1]+'["][name$="]"]';
    }else{
      selector += '[name="'+name+'"]';
    }
    $(selector, $form).not($t).prop('checked',false);
  });

This code on jsFiddle

Community
  • 1
  • 1
Luke Stevenson
  • 10,357
  • 2
  • 26
  • 41
0
<html>
<body>

<form action="#" method="post">
Radio 1: <input type="radio" name="radioMark" value="radio 1" /><br />
Radio 2: <input type="radio" name="radioMark" value="radio 2" /><br />
<input type="submit" value="Submit" />
</form>

</body>
</html>

Ultimately you can use brackets with the name attribute to create an array of radio input like so:

<input type="radio" name="radioMark[]" value="radio1" />Radio 1
<input type="radio" name="radioMark[]" value="radio2" />Radio 2
<input type="radio" name="radioMark[]" value="radio3" />Radio 3
<input type="radio" name="radioMark[]" value="radio4" />Radio 4

What matters to transfer in the end are whats in the value attribute. Your names do not have to be different at all for each radio button. Hope that helps.

robx
  • 3,093
  • 2
  • 26
  • 29
0

Using Knockout JS

var viewModel = { 
        isMale: ko.observable(false),
        isFemale: ko.observable(false),
    };

    $(document).ready(function(){
        ko.applyBindings(viewModel)
    });

    function setCheckBox() {
        viewModel.isFemale(false)
        viewModel.isMale(false)
    };
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<input type="checkbox" id="chkMale" name="male" data-bind="checked: isMale" class="gender" onclick="setCheckBox(this)"/>
<label for="chkMale"> MALE</label>
        
<input type="checkbox" id="chkFemale" name="female" data-bind="checked: isFemale" class="gender" onclick="setCheckBox(this)"/>
<label for="chkFemale"> FEMALE</label>
MD SAIF
  • 1
  • 2