Link to home
Start Free TrialLog in
Avatar of davidcahan
davidcahanFlag for United States of America

asked on

Javascript that allows only one CheckBoxList item to be selected

I need javascript that basically makes a checkboxlist behave like a radiobuttonlist in that only one item can be checked.  Unfortunately i have a client that is insisting that they want the UI to be checkboxes and not radiobuttons (or else i would just use a radiobuttonlist).  I've tried a few different sets of code i found online.  one set doesn't work at all.  the other, which i have attached below, only works in IE and not firefox.
var objChkd;
 
    function HandleOnCheck() {
 
        var chkLst = document.getElementById(this);
 
 
        if (objChkd && objChkd.checked)
            objChkd.checked = false;
 
        objChkd = event.srcElement;
 
 
    }

Open in new window

Avatar of aibusinesssolutions
aibusinesssolutions
Flag of United States of America image

This is working in both Firefox and IE.
<script type="text/javascript">
    function SingleSelect(regex, current) {
        re = new RegExp(regex);
        for (i = 0; i < document.forms[0].elements.length; i++) {
            elm = document.forms[0].elements[i];
            if (elm.type == 'checkbox') {
                if (re.test(elm.name)) {
                    elm.checked = false;
                }
            }
        }
        current.checked = true;
    }
</script>
 
 
 
    aaaa<input type="checkbox" id="chkOne" name="chkOne" value="aaaa" checked onclick="SingleSelect('chk',this);" />
    <br />
    bbbb<input type="checkbox" id="chkTwo" name="chkTwo" value="bbbb" onclick="SingleSelect('chk',this);" />
    <br />
    cccc<input type="checkbox" id="chkThree" name="chkThree" value="cccc" onclick="SingleSelect('chk',this);" />
    <br />
    dddd<input type="checkbox" id="chkFour" name="chkFour" value="dddd" onclick="SingleSelect('chk',this);" />
    <br />
    eeee<input type="checkbox" id="chkFive" name="chkFive" value="eeee" onclick="SingleSelect('chk',this);" />

Open in new window

Note that the RegEx is looking for checkboxes with "chk" in their ID, this is so you can make separate groups of checkboxes, without unchecking every checkbox on the page.
Avatar of davidcahan

ASKER

are you sure that works on a checkboxlist control?
Yes, it basically loops through every form element on your form, and looks for form controls with type="checkbox".

You may need to loop through the checkboxlist on page_load and add the onclick attributes to the individual checkboxes.
Avatar of Kin Fat SZE

<script type="text/javascript">
    function formOnClickEvent(e,formObj) {
      var childs;
      if(window.event) // IE
      {
        keynum = e.keyCode;
        ctrlKey  = e.ctrlKey;
        EventObj = e.srcElement;
      }
      else if(e.which) // Netscape/Firefox/Opera
      {
        keynum = e.which;
        ctrlKey = e.ctrlKey;
        EventObj = e.target;
      }
      
      childs = formObj.elements;
      
      for (i=0;i<childs.length;i++){
        if (childs[i].type == 'checkbox'){
          childs[i].checked=false;
        }
      }
    }
</script>
 
 
 <form name="form1" onmouseup="formOnClickEvent(event,this);">
    <input type="checkbox" name="checkbox1" checked  />
    <br />
    <input type="checkbox" name="checkbox2" />
    <br />
    <input type="checkbox" name="checkbox3" />
    <br />
    <input type="checkbox" name="checkbox4" />
    <br />
    <input type="checkbox" name="checkbox5" />
    <input type="text">
    </form>

Open in new window

Avatar of funwithdotnet
funwithdotnet

Perhaps this will help:

<script type="text/javascript">
// Javascript inside <head> tag.
function checkBoxRadio(someCheckbox) // Triggered by the checkbox onclick event.
{
	var x = someCheckbox
	// Set of checkboxes to act as a radio group.
<%=CheckBoxItems %>
}
 
function uncheckBox(myCheckBox, testCheckbox)
{	
	var x = myCheckBox
	var y = testCheckbox
	if (x != y) {
		y.checked = false;
	}
}
</script>
 
 
' in VB code
Protected Sub SomeSub()
	Dim x As Integer
	For x = 0 To CheckBoxList1.Items.Count - 1
		Dim myListItem As ListItem = CheckBoxList1.Items(x)
		myListItem.Attributes.Add("onclick", "checkBoxRadio(this);") 'onclick="checkBoxRadio(this);
		CheckBoxItems &= vbTab & "uncheckBox(x, document.getElementById(""" & CheckBoxList1.ID.ToString & "_" & x.ToString & """))" & vbCrLf
	Next
End Sub

Open in new window

above comment have bug, try this
<script type="text/javascript">
    function formOnClickEvent(e,formObj) {
      var childs;
      if(window.event) // IE
      {
        EventObj = e.srcElement;
      }
      else if(e.which) // Netscape/Firefox/Opera
      {
        EventObj = e.target;
      }
      
      childs = formObj.elements;
      
    if (EventObj.type == 'checkbox'){
      for (i=0;i<childs.length;i++){
        if (childs[i].type == 'checkbox' && (EventObj != childs[i])){
          childs[i].checked=false;
        }
      }
    }
//      alert(EventObj.checked);
//      EventObj.checked=true;
    }
</script>
 
 
 <form name="form1" onmouseup="formOnClickEvent(event,this);">
    <input type="checkbox" name="checkbox1" checked  />
    <br />
    <input type="checkbox" name="checkbox2" />
    <br />
    <input type="checkbox" name="checkbox3" />
    <br />
    <input type="checkbox" name="checkbox4" />
    <br />
    <input type="checkbox" name="checkbox5" />
    <input type="text">
    </form>

Open in new window

one issue i'm seeing is that i'm going to have more than one checkboxlist control on the page.  if this loops through every checkbox on the page then it looks like it will not work for my situation.  isn't there some way i can wire the javascript directly to the checkboxlist instead of to the form.  i know that the following will get me the input tags for a particular checkboxlist

var chkControlId = 'CheckBoxListID';
var options = document.getElementById(chkControlId).getElementsByTagName('input');

each input should be a type=checkbox.  I don't know where to go from this point to check only the one I select and uncheck all the others but by using the above as a starting point shouldn't we be able to hook an onClick even directly to each checkboxlist?

The solution that I gave you will work for that.  Just name the groups of check boxes differently.

With my script, just make sure you set the name of the CheckBoxList in the attributes add.

For example, if the control is named CheckBoxList1, then you would do this:
chk.Attributes.Add("onclick", "SingleSelect('CheckBoxList1',this)")

Here's an example:


Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not IsPostBack Then
            For Each chk As ListItem In CheckBoxList1.Items
                chk.Attributes.Add("onclick", "SingleSelect('CheckBoxList1',this)")
            Next
            For Each chk As ListItem In CheckBoxList2.Items
                chk.Attributes.Add("onclick", "SingleSelect('CheckBoxList2',this)")
            Next
        End If
End Sub

Open in new window

OR.....  If you have a ton of checkboxlists on your page, you can do this.
For Each ctl As Control In form1.Controls
   If ctl.GetType.Name = "CheckBoxList" Then
      Dim cbl As CheckBoxList = ctl
      For Each chk As ListItem In cbl.Items
         chk.Attributes.Add("onclick", "SingleSelect('" & cbl.ID & "', this)")
      Next
   End If
Next

Open in new window

i'm going to have more than one checkboxlist control on the page?
can you add attribute *group* to specify each checkboxlist control ?

two functions are works
formOnClickEvent (form onmouseup event)
unSelectCheckBox (checkbox onclick event)
<script type="text/javascript">
    function formOnClickEvent(e,formObj) {
      var childs;
      var group;
      if(window.event) // IE
      {
        EventObj = e.srcElement;
      }
      else if(e.which) // Netscape/Firefox/Opera
      {
        EventObj = e.target;
      }
      
      
      childs = formObj.elements;
//      alert(EventObj.attributes['group'].value);
    if (EventObj.type == 'checkbox'){
      group = EventObj.attributes['group'].value;
      for (i=0;i<childs.length;i++){
        if (childs[i].type == 'checkbox' && childs[i].attributes['group'].value == group && (EventObj != childs[i])){
          childs[i].checked=false;
        }
      }
    }
//      alert(EventObj.checked);
//      EventObj.checked=true;
    }
</script>
 
 
 <form name="form1" onmouseup="formOnClickEvent(event,this);">
<br/>
group 1<br/>
    <input type="checkbox" name="checkbox1" group="group1" checked  />
    <br />
    <input type="checkbox" name="checkbox2" group="group1"  />
    <br />
    <input type="checkbox" name="checkbox3" group="group1"  />
    <br />
    <input type="checkbox" name="checkbox4" group="group1"  />
    <br />
    <input type="checkbox" name="checkbox5" group="group1"  />
<br/>
group 2<br/>
    <input type="checkbox" name="checkbox4" group="group2"  />
    <br />
    <input type="checkbox" name="checkbox5" group="group2"  />
 
    <input type="text">
    </form>

Open in new window

SOLUTION
Avatar of CB_Thirumalai
CB_Thirumalai
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
davidcahan: "isn't there some way i can wire the javascript directly to the checkboxlist instead of to the form."

The example I provided does that and allows you to manage it in .NET. The only thing I left out is the variable declaration to hold the dynamically-produced javascript (Protected CheckBoxItems As String). Other things you may wish to do is have the method accept a parameter and/or generate javascript functions in code. The example I provided also shows how to do that.
I really don't want to sound like i'm looking a gift horse in the mouth because i'm not.  there are some really great solutions in here.  and i'm not very good with javascript (hence the post) so again, i don't want to sound like a petulant child. but i really wish i could get a solution where the onClick event is tied to the checkboxlist without the need to add it to each checkbox item.  

ie -- <asp:CheckBoxList ID="cbPlanVac" onClick="ThereCanBeOnlyOne();" RepeatColumns="5" RepeatDirection="Horizontal" runat="server"></asp:checkboxlist>  

the original code i posted did that.  unfortunately it didn't work in firefox.  i guess i was thinking that someone would take that and mod it. perhaps it isn't possible to tie the onClick at that level and have it work in both firefox and  IE .  anyway, tell me it's impossible and i'll move on.  my head just keeps getting stuck there.

thanks everyone and again I hope i'm not coming across like a jerk
I think the code that CB wrote is probably the closest to what you are wanting.  His goes from the checkbox to the parent until it finds a table.  It might be possible to re-write it so it searches for child objects that are checkboxes, instead of searching parent objects.
hope i don't piss anyone off but CB_Thirumalai was the solution that fit best.