I found something here, but I'm not good at javascript, and i don't know which part of the code is the right! I need only for Checkboxes!

http://www.codingforums.com/showthread.php?t=11165

I need something like:
onclick="check_if_at_least_one_is_selected()" :P

there is only one <form></form> and all checkboxes are same type...

Recommended Answers

All 21 Replies

Here you have it:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Test Page</title>
<script type="text/javascript">
<!--
check = function( form ) {
   try { 
      with( form ) { // Dual Mode 
         if (!( chb0.checked ) && !( chb1.checked )) {
        alert( "You must atleast select 1 item in the field.");
     return false;
         } else { 
           (( chb0.checked ) ? alert( "You've selected the following item:\n" + chb0.value ) : alert( "You've selected the following item:\n" + chb1.value )); }
      } 
   } catch( e ) {
              if (!( form.chb0.checked ) && !( form.chb1.checked )) {
        alert( "You must atleast select 1 item in the field.");
     return false; } else { 
           (( form.chb0.checked ) ? alert( "You've selected the following item:\n" + form.chb0.value ) : alert( "You've selected the following item:\n" + form.chb1.value )); 
      }
   }
} 
// -->
</script>
</head>
<body>
<form id="frm" action="#" onsubmit="return check( this );">
<div>
<label for="chb0">Check Field1: <input type="checkbox" id="chb0" name="chb0" value="CheckBox #1"></label><br> 
<label for="chb1">Check Field2: <input type="checkbox" id="chb1" name="chb1" value="CheckBoX #2"></label><br><br>
<input type="submit" value="submit" id="sbm" name="sbm">
</div>
</form>
</body>
</html>

Will this find cheboxes that do not Have chbX as a name/id?

Cuz my checkboxes are like this:

<input type="checkbox" name="792" value="Tekzilla Daily Tip" />
<input type="checkbox" name="791" value="Daily Motion" />
<input type="checkbox" name="789" value="Search" />

All checkboxes have id's like this! & I need to check if at least ONE of ALL checkboxes are checked... no matter what ID/NAME!

It will search whatever ids you will provide. Just make sure that it's a valid one, and valid ids should start with alphabetic character's like: a791, chb791, etc.

you must provide your own ids for the element's inside your document, you don't have to use chb0 which is stated in posted code. Don't worry i'll provide another brief example for this issue.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Test Page</title>

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() 
{
	//Listens for form id "frm" to be submitted
	//When submitted checks if 1 or more checkboxes are checked.
	$('#frm').submit( function() {
		
		//Look for ONLY checked inputs under this form
		var n = $('#frm :checked').length;
		
		//If we have 1 or more show how many
		if( n > 0 ){ alert( n + ' are checked' ); }
		//Else show we have none that are checked
		else { alert( 'none are checekd' ); }
		
		//Prevents form submission for demo
		return false;
	});
});
</script>

</head>
<body>
<form id="frm" action="#">
<div>
<label for="chb0">Check Field1: 
	<input type="checkbox" id="chb0" name="chb0" value="CheckBox #1">
</label><br> 
<label for="chb1">Check Field2: 
	<input type="checkbox" id="chb1" name="chb1" value="CheckBoX #2">
</label><br><br>
<input type="submit" value="submit" id="sbm" name="sbm">
</div>
</form>
<input type="checkbox" id="chb1" name="chb1" value="CheckBoX #2">
</body>
</html>

If you're going to be using javascript throughout your project I'd highly suggest looking at a library like jQuery. It will make you life much easier and the amount of power you gain as well as its cross browser compatibility is amazing.

This example illustrates checking if 1 or more checkboxes in your form a checked. the checkbox that is outside of the form will not contribute to the overall count. It also does NOT care what the inputs are named or their ids. It is looking for ANY input that is checked in your form which has an #id of frm. It also does not require any javascript to pollute your HTML.

Strip my comments out and you have about 5 lines of JS that are easy to understand.

http://docs.jquery.com/Main_Page

This will automatically check all checkboxes item's in your document. And doesn't need any editing.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<title>Test Page</title>
<script type="text/javascript">
// <![CDATA[
var check;

check = function( e ) {
   e = (( e ) ? e : window.event );
   t = (( e.target ) ? e.target : e.srcElement );
   if (( t.nodeName.toLowerCase() === "input" ) && ( t.type === "checkbox" && t.checked )) {
   alert( "You have checked the following item: " + t.value );
   val = (( t.checked ) ? "You've checked this item: <br />" + t.value : "" );
   (( document.getElementById ) ? document.getElementById("output").innerHTML = val : document.all.output = val );
   t.checked = false;
   }
};
document.onclick = check;
// ]]>
</script>
</head>
<body>
<div id="main">
<form id="myform" action="#" onsubmit="return false;">
<div>
<label for="c792">Tekzilla Daily Tip <input type="checkbox" id="c792" name="c792" value="Tekzilla Daily Tip" /></label><br />

<label for="c791">Daily Motion <input type="checkbox" id="c791" name="c791" value="Daily Motion" /></label><br />
<label for="c789">Search <input type="checkbox" id="c789" name="c789" value="search" /></label>
<!-- You can add more checkboxes here -->
</div>
</form>
</div>
<div id="output"></div>
</body>
</html>

The following code will also work on all major browsers EXCEPT Internet Explorer and IE-based browsers: index.html

<html>
<head>
<script type="text/javascript" src="form_validate.js">
// Script created 2009 KnifeySpooney
// http://wurbo.com
//
// Completely free to use and modify
</script>
</head>

<body>

<form action="submit.php" method="get" onSubmit="validate(this); return false;">
	Test <input type="checkbox"/><br/>
	Test <input type="checkbox"/><br/>
	Test <input type="checkbox"/><br/>
	Test <input type="checkbox"/><br/>
	Test <input type="checkbox"/><br/>
	Test <input type="checkbox"/><br/>
	Test <input type="checkbox"/><br/>
	Test <input type="checkbox"/><br/>
	Test <input type="checkbox"/><br/>
	Test <input type="checkbox"/><br/>
	Test <input type="checkbox"/><br/>
	Test <input type="checkbox"/><br/>
	Test <input type="checkbox"/><br/>
	Test <input type="checkbox"/><br/>
	<br/><input type="submit" value="Submit"/>
</form>

</body>
</html>

form_validate.js

function validate(form) {
	var checkList = 0;
	var checks = document.evaluate(".//input[@type='checkbox']", form, null, 6, null);

	for (var i=0; i<checks.snapshotLength; i++) {
		if (checks.snapshotItem(i).checked)
			checkList++;
	}

	if (checkList > 0) {
		if (checkList == 1)
			alert("There was " + checkList + " checkbox marked.");
		else
			alert("There were " + checkList + " checkboxes marked.");
	}
	else
		alert("No checkboxes were marked.");
}

Poor smartness - advice overload I expect ......

..... but please let me join in.

This code:

  1. will validate as many independent groups of checkboxes as you like.
  2. will, on failure to validate :
    1. set a message in an HTML element of your choosing (by id), for each group independently, or
    2. give a javascript alert if no HTML element is provided for error messages
  3. is controlled from the HTML without needing to edit the javascript (except if you want different error messages, though that could be set in HTML too).
  4. works on IE and Firefox.
  5. is only 4 lines of code (if you put the worker function into a lib)!!!!

That said, I must give jquery a go some time.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Test Page</title>
<style type="text/css">
html,body { font-size:10pt; }
.checkBoxGroup  { width:150px; margin:6px 0 0 0; padding:5px; border:1px solid #999999; }
.checkBoxGroup h3 { margin:0; }
p.errMsg { margin:0 0 9px 0; color:red; }
</style>

<script type="text/javascript">
check = function( form, chBoxGroups ) {
	result = true;
	if (chBoxGroups){ result = chBoxGroupValidator.scanGroups(chBoxGroups) && result; }
	//result = foo1() && result; //Do other checks here as necessary.
	//result = foo2() && result; //Do other checks here as necessary.
	//result = foo3() && result; //Do other checks here as necessary.
	return result;
}
var chBoxGroupValidator = function(){
	var setMsg = function(group, msg){
		var msgID = group.getAttribute('msgID');
		if(!msgID) { return false; }
		var msgEl = (document.getElementById) ? document.getElementById(msgID) : document.all[msgID];
		if(!msgEl) { return false; }
		msgEl.innerHTML = msg;
		return true;
	};
	var validateGroup = function(groupID){
		if (!groupID || typeof groupID != 'string') { return true; };//Invalid groupID - assume good.
		var qualifiers = false;
		var group = (document.getElementById) ? document.getElementById(groupID) : document.all[groupID];
		if(!group) { return true; }//group not found - assume good.
		var inputElements = group.getElementsByTagName('INPUT');
		for(var i=0; i<inputElements.length; i++) {
			if(inputElements[i].getAttribute('type') == 'checkbox') {
				qualifiers = true;
				if(inputElements[i].checked) {
					setMsg(group, '&nbsp;');
					return true;
				}
			}
		}
		if(qualifiers) {
			if( !setMsg(group, 'Select at least one item in this group') ) {
				var groupName = group.getAttribute('name');
				alert( ['You must select at least one item in the group : ', ((!groupName) ? '' : groupName)].join('') );
			}
			return false;
		}
		return true;
	};
	return {
		scanGroups : function(chBoxGroups){
			if (!chBoxGroups) { return true; }
			var result = true;
			if(typeof chBoxGroups == 'string') { chBoxGroups = [chBoxGroups]; }
			if(chBoxGroups.length) {
				for(var i=0; i<chBoxGroups.length; i++) { result = validateGroup(chBoxGroups[i]) && result; }
			}
			return result;
		}
	};
}();
</script>
</head>
<body>
<form id="frm" action="#" onsubmit="return check( this, ['group_1', 'group_2'] );">
<div id="group_1" name="Group 1" msgID="msg_1" class="checkBoxGroup">
	<h3>Group 1</h3>
	<label for="ch1_1">Check Field 1_1: <input type="checkbox" id="ch1_1" name="ch1_1" value="CheckBox 1_1"></label><br>
	<label for="ch1_2">Check Field 1_2: <input type="checkbox" id="ch1_2" name="ch1_2" value="CheckBoX 1_2"></label><br>
</div>
<p id="msg_1" class="errMsg">&nbsp;</p>
<div id="group_2" name="Group 2" msgID="msg_2" class="checkBoxGroup">
	<h3>Group 2</h3>
	<label for="ch2_1">Check Field 2_1: <input type="checkbox" id="ch2_1" name="ch2_1" value="CheckBox 2_1"></label><br>
	<label for="ch2_2">Check Field 2_2: <input type="checkbox" id="ch2_2" name="ch2_2" value="CheckBoX 2_2"></label><br>
	<label for="ch2_3">Check Field 2_3: <input type="checkbox" id="ch2_3" name="ch2_3" value="CheckBoX 2_3"></label><br>
</div>
<p id="msg_2" class="errMsg">&nbsp;</p>
<input type="submit" value="submit" id="sbm" name="sbm2">
</form>
</body>
</html>

By the way, there's nothing wrong with the other guys' code. There are many ways to approach this.

Airshow

commented: Great post in the Checkbox thread :D +1
commented: Excellent +0

Airshow, your script is awesome! Thank you for sharing it. I was hoping you could help me edit it a bit.

I have different groups and I want to be able to have the submission go through if any check box is checked in any group instead of having to have a check box in both groups being checked.

Is there a way to just edit the code in the code in the form container instead of editing the script? Somthing like this:

onsubmit="return check( this, ['group_1' or 'group_2'] )"

Jeffshead,

If I understand correctly, as far as my code is concerned, you need just one group, wrapped in:

<div id="group_1" name="Group 1" msgID="msg_1" class="checkBoxGroup">
...
</div>

You just need to lay out the checkboxes within this div such that the checkboxes are visually organised into separate sections (use brs or nested divs to achieve the effect).

With one group, the form's onsubmit will read:

onsubmit="return check( this, ['group_1'] );"

Airshow

Sorry, let me try again. I have a page that is poorly laid out. Because it uses a templating system, it would be very difficult to change. The problem I have is that the form items are in different tables and div's so the form is not in one container and if I try to wrap this particular page/template with one div or table, it ruins the layout.

I need your script to check two different containers/groups to see if any one check box is ticked. I do not require a check box to be ticked in both groups. Just either or.

If you can't insert your own container you still have the option of using one that already exists, and the prime candidate is the form itself.

In my example, the form has id="frm" , so the onsubmit handler would be as follows:

<form id="frm" action="#" onsubmit="return check( this, ['frm'] );">

This will treat the form as the container of one group of chekboxes and will return true if any one checkbox within the entire form is checked.

If you have two or more "groups" of checkboxes intermingled within the form, then the code would need to be modified. The easiest approach would be to test for a className at line 38 but there would need to be other mods too.

Airshow

If you have two or more "groups" of checkboxes intermingled within the form...

That's the issue I have.

The easiest approach would be to test for a className at line 38 but there would need to be other mods too.

This is what I need. Can you tell me what to change? I tried but since I don't know what I'm doing, it did not work.

Jeffshead,

No shame in having failed. The mods are quite extensive.

Try this:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Test Page</title>
<style type="text/css">
html,body { font-size:10pt; }
.checkBoxGroup  { width:150px; margin:6px 0 0 0; padding:5px; border:1px solid #999999; }
.checkBoxGroup h3 { margin:0; }
p.errMsg { margin:0 0 9px 0; color:red; }
</style>

<script type="text/javascript">
var CHBOX_GROUP_VALIDATOR = function(){//Namespace pattern
	var validateGroup = function(groupData){
		var className, container, msgID, testFn;
		switch(groupData.groupBy){
			case 'container':
				container = (document.getElementById) ? document.getElementById(groupData.value) : (document.all) ? document.all[groupData.value] : document;
				testFn = function(el){ return true; };
			break;
			case 'className':
				container = document;
				className = groupData.value;
				testFn = function(el){return el.className.match(className)};
			break;
		}
		msgID = groupData.msgID;
		if (!container) { return true; };//Invalid container - assume good.
		var qualifiers = false;
		var inputElements = container.getElementsByTagName('INPUT');
		for(var i=0; i<inputElements.length; i++) {
			var el = inputElements[i];
			if( el.getAttribute('type') == 'checkbox' && testFn(el) ) {
				qualifiers = true;
				if(el.checked) {
					setMsg(msgID, '&nbsp;');
					return true;
				}
			}
		}
		if(qualifiers) {
			var msg = 'Select at least one item in the group: ' + groupData.name;
			if( !msgID || !setMsg(msgID, msg) ) { alert(msg); }
			return false;
		}
		return true;
	};
	var setMsg = function(msgID, msg){
		if(!msgID) { return false; }
		var msgEl = (document.getElementById) ? document.getElementById(msgID) : (document.all) ? document.all[msgID] : null;
		if(!msgEl) { return false; }
		msgEl.innerHTML = msg || '';
		return true;
	};
	var scanGroups = function(chBoxGroups){
		if (!chBoxGroups) { return true; }
		var result = true;
		if(chBoxGroups.length) {
			for(var i=0; i<chBoxGroups.length; i++) { result = validateGroup(chBoxGroups[i]) && result; }
		}
		return result;
	};
	return {
		scanGroups: scanGroups
	};
}();
check = function(form, scanArray) {
	result = true;
	if (scanArray){ result = CHBOX_GROUP_VALIDATOR.scanGroups(scanArray) && result; }
	//result = foo1() && result; //Do other checks here as necessary.
	//result = foo2() && result; //Do other checks here as necessary.
	//result = foo3() && result; //Do other checks here as necessary.
	return result;
}
</script>
</head>
<body>
<form id="frm" action="#" onsubmit="return check( this, [
	{groupBy:'container', name:'Group1', value:'group_1', msgID:'msg_1'}, 
	{groupBy:'container', name:'Group2', value:'group_2', msgID:'msg_2'}, 
	{groupBy:'className', name:'GroupA', value:'group_A', msgID:'msg_A'}
] );">
<div id="group_1" name="Group 1" msgID="msg_1" class="checkBoxGroup">
	<h3>Group 1</h3>
	<label for="ch1_1">Check Field 1_1: <input type="checkbox" id="ch1_1" name="ch1_1" value="CheckBox 1_1"></label><br>
	<label for="ch1_2">Check Field 1_2: <input type="checkbox" id="ch1_2" name="ch1_2" value="CheckBoX 1_2"></label><br>
</div>
<p id="msg_1" class="errMsg">&nbsp;</p>
<label for="chA_1">Check Field A_1: <input type="checkbox" id="chA_1" name="chA_1" class="group_A" value="CheckBox A_1"></label><br>
<label for="chA_2">Check Field A_2: <input type="checkbox" id="chA_2" name="chA_2" class="group_A" value="CheckBoX A_2"></label><br>
<div id="group_2" name="Group 2" class="checkBoxGroup">
	<h3>Group 2</h3>
	<label for="ch2_1">Check Field 2_1: <input type="checkbox" id="ch2_1" name="ch2_1" value="CheckBox 2_1"></label><br>
	<label for="ch2_2">Check Field 2_2: <input type="checkbox" id="ch2_2" name="ch2_2" value="CheckBoX 2_2"></label><br>
	<label for="ch2_3">Check Field 2_3: <input type="checkbox" id="ch2_3" name="ch2_3" value="CheckBoX 2_3"></label><br>
</div>
<p id="msg_2" class="errMsg">&nbsp;</p>
<label for="chA_3">Check Field A_3: <input type="checkbox" id="chA_3" name="chA_3" class="group_A" value="CheckBox A_3"></label><br>
<label for="chA_4">Check Field A_4: <input type="checkbox" id="chA_4" name="chA_4" class="group_A" value="CheckBoX A_4"></label><br>
<p id="msg_A" class="errMsg">&nbsp;</p>
<input type="submit" value="submit" id="sbm" name="sbm3">
</form>
</body>
</html>

Notes:

  • The code allows checkboxes to "grouped" by container or by className. Both types of group can coexist, as in the example.
  • Checkboxes grouped by className can be intermingled with other checkboxes.
  • Groups are specified in an array of objects in the form's onload attribute.

Airshow

Airshow,

Thank you so very much. I tested the script as is and it works great but I can't use it on my website because it uses the Smarty templating system. The { and } characters are being interpreted and breaking the page and causing PHP errors.

Can those characters be replaced with something else?

I forgot to mention that I can put the JavsScript in a sperate file and call it, so the only { and } characters I have to worry about are the ones in the onsubmit event which are actually coded on the webpage.

This works for Smarty:

onsubmit="return check( this, [ {literal}{{/literal}groupBy:'className', name:'GroupA', value:'group_A', msgID:'msg_A'{literal}}{/literal} ] );"

Thanks again. Your kindness and time are much appreciated :icon_wink:

Jeffshead,

I only used Smarty very briefly a couple of years ago. This page confirms your {literal}...{/literal} approach and makes other suggestions.

For me, the preferred approach would be to move the event handler off the page, into the .js file with the other javascript. That's considered best practice on every occasion, smarty or not. My original code in this topic was written over two years ago when I was less disciplined - that's my excuse for not having done things correctly in the first place.

Attachment of event handlers in javascript needs to performed after the HTML has loaded, otherwise the code will be trying to act on DOM elements that do not yet exist. The best approach is to attach event handlers inside a window.onload handler, which safely fires after the document has fully loaded.

First add the following to the end of the .js file into which you have already moved all the other js code :

window.onload = function(){
  var f  = document.forms["frm"];
  if(f){
    f.onsubmit = function(){
      return check(this, [
        {groupBy:'container', name:'Group1', value:'group_1', msgID:'msg_1'}, 
        {groupBy:'container', name:'Group2', value:'group_2', msgID:'msg_2'}, 
        {groupBy:'className', name:'GroupA', value:'group_A', msgID:'msg_A'}
      ]);
    };
  }
};

As you will see, this is basically the same code as before but now in a javascript function wrapper instead of an HTML wrapper. OK, we have to do something extra; namely find the form node in the DOM, so the handler can be attached to it, but that's all.

Now reduce the form tag to :

<form id="frm" action="#">

Unless I have made a mistake in this untested code, it should work even when the HTML is sent via the Smarty parser.

Airshow

@smartness [post#1]

This will do just fine:

function ifChecked(form){for(x in form.elements)if(form.elements[x].checked)return!0}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.