Poor smartness - advice overload I expect ......
..... but please let me join in.
This code: will validate as many independent groups of checkboxes as you like.
will, on failure to validate :set a message in an HTML element of your choosing (by id), for each group independently, or
give a javascript alert if no HTML element is provided for error messages
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).
works on IE and Firefox.
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, ' ');
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>
<label for="ch1_2">Check Field 1_2: <input type="checkbox" id="ch1_2" name="ch1_2" value="CheckBoX 1_2"></label>
</div>
<p id="msg_1" class="errMsg"> </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>
<label for="ch2_2">Check Field 2_2: <input type="checkbox" id="ch2_2" name="ch2_2" value="CheckBoX 2_2"></label>
<label for="ch2_3">Check Field 2_3: <input type="checkbox" id="ch2_3" name="ch2_3" value="CheckBoX 2_3"></label>
</div>
<p id="msg_2" class="errMsg"> </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
Airshow
WiFi Lounge Lizard
2,683 posts since Apr 2009
Reputation Points: 321
Solved Threads: 372
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
Airshow
WiFi Lounge Lizard
2,683 posts since Apr 2009
Reputation Points: 321
Solved Threads: 372
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
Airshow
WiFi Lounge Lizard
2,683 posts since Apr 2009
Reputation Points: 321
Solved Threads: 372
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, ' ');
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>
<label for="ch1_2">Check Field 1_2: <input type="checkbox" id="ch1_2" name="ch1_2" value="CheckBoX 1_2"></label>
</div>
<p id="msg_1" class="errMsg"> </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>
<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>
<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>
<label for="ch2_2">Check Field 2_2: <input type="checkbox" id="ch2_2" name="ch2_2" value="CheckBoX 2_2"></label>
<label for="ch2_3">Check Field 2_3: <input type="checkbox" id="ch2_3" name="ch2_3" value="CheckBoX 2_3"></label>
</div>
<p id="msg_2" class="errMsg"> </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>
<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>
<p id="msg_A" class="errMsg"> </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
WiFi Lounge Lizard
2,683 posts since Apr 2009
Reputation Points: 321
Solved Threads: 372