Link to home
Start Free TrialLog in
Avatar of koila
koilaFlag for Australia

asked on

Mandatory field required for a checkbox and radio button.

I have this code which is working fine.

When I implemented into my code is not making my question 1 and question 2 mandatarory field.

<h4>Check a vegetable, and at least one fruit</h4>
<form action="" method="post" name="f1" onsubmit="return checkButons(this);">
Vegetables: <input type="radio" name="vegetable" value="cabbage" />Cabbage
 <input type="radio" name="vegetable" value="carrot" />Carrot<br/>
Fruits:<br/>
 <input type="checkbox" name="fruit1" value="apple" />Apple<br/>
 <input type="checkbox" name="fruit2" value="pear" />Pear<br/>
 <input type="checkbox" name="fruit3" value="banana" />Banana<br/>
 <input type="submit" value="Submit" />
</form>
<script type="text/javascript"><!--
// checks buttons (radio, checkbox) - coursesweb.net
function checkButons(frm) {
var re = false;           // used to determine when a button is checked
var err = '';             // to store the errors

var vegetables = frm.vegetable;          // contains an array with all radio buttons "vegetable"

// create an Array in JSonn format with checkbox buttons
var fruits = [frm.fruit1, frm.fruit2, frm.fruit3];

// traverse the radio buttons
// if one is checked sets re to true, and stops the iteration with "break"
for(var i=0; i<vegetables.length; i++) {
  if(vegetables[i].checked == true) {
    re = true;
    break;
  }
}

// if "re" is false means no radio button checked, add error in "err" 
if(re == false) err += '- You must check at least one vegetable';

// make "re" again False, and traverse the checkbox buttons
// if one is checked sets re to true, and stops the iteration with "break"
re = false
for(var i=0; i<fruits.length; i++) {
  if(fruits[i].checked == true) {
    re = true;
    break;
  }
}

// if "re" is false means no checkbox button checked, add error in "err" 
if (re == false) err += '\n - You must check at least one fruit';

// if "err" not empty, alert the error(s) and returns False to stop submitting form
if(err != "") {
  alert(err);
  return false;
}
else return re;
}
--></script>

Open in new window


source: http://coursesweb.net/javascript/validate-radio-checkbox-buttons_t

I have change the script to this one into my code.

Please view attached
MyTestFormLayout.jpg
MyTestForm.txt
ASKER CERTIFIED SOLUTION
Avatar of Jim Horn
Jim Horn
Flag of United States of America 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
Avatar of koila

ASKER

Please review my attached code and pls tell me what is wrong?  Please advise
Skill set = Bit data type
Committee = single tinyint (if not more than 8 options) if more than go with single smallint and use boolean logic as in:
POL = 2 ^ 0 = 1
SOP = 2 ^ 1 = 2
EE = 2 ^ 2 = 4
ADMIN = 2 ^ 3 = 8
TF = 2 ^ 4 = 16
ANY= 2 ^ 5 = 32
SP= 2 ^ 6 = 64
The code you posted above didn't work for me until i changed it to this:

// checks buttons (radio, checkbox) - coursesweb.net
function checkButons(frm) {
  var re = false;           // used to determine when a button is checked
  var err = '';             // to store the errors
  
  var vegetables = frm.vegetable;          // contains an array with all radio buttons "vegetable"
  
  // create an Array in JSonn format with checkbox buttons
  var fruits = [frm.fruit1, frm.fruit2, frm.fruit3];
  
  // traverse the radio buttons
  // if one is checked sets re to true, and stops the iteration with "break"
  for(var i=0; i<vegetables.length; i++) {
    console.log(vegetables[i].checked);
    if(vegetables[i].checked === true) {
      re = true;
      break;
    }
  }
  
  // if "re" is false means no radio button checked, add error in "err" 
  if(re === false) err += '- You must check at least one vegetable';
  
  // make "re" again False, and traverse the checkbox buttons
  // if one is checked sets re to true, and stops the iteration with "break"
  re = false;
  for(i=0; i<fruits.length; i++) {
    if(fruits[i].checked === true) {
      re = true;
      break;
    }
  }
  
  // if "re" is false means no checkbox button checked, add error in "err" 
  if (re === false) err += '\n - You must check at least one fruit';
  
  // if "err" not empty, alert the error(s) and returns False to stop submitting form
  if(err !== "") {
    alert(err);
    return false;
  }
  else return re;
}

Open in new window


see here: http://jsbin.com/ILeBInE/1/edit
for starters you html doesn't validate... why do you have this twice?

<html xmlns="http://www.w3.org/1999/xhtml">
<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<html>
<head>


just one of many errors.

please use http://validator.w3.org/#validate_by_input and paste your page into that
Here is the working Code for your Issue, I corrected the Invalid HTML and added the function to the onclick event rather than on onsubmit, According to w3schools, you should add the function on the submit button:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<head>
<title>Form |</title>
</head>
<script type="text/javascript">
// checks buttons (radio, checkbox) - coursesweb.net
function checkButons(frm) {
var re = false;           // used to determine when a button is checked
var err = '';             // to store the errors

//var question1 = document.getElementById('contactme').checked;          // contains an array with all radio buttons "vegetable"
//alert(question1);
// create an Array in JSonn format with checkbox buttons
//var question2 = [frm.CMTEE_PREF_NEW];
// traverse the radio buttons
// if one is checked sets re to true, and stops the iteration with "break"
for(var i=0; i<frm.contactme.length; i++) {
  if(frm.contactme[i].checked) {
    re = true;
    break;
  }
}
// if "re" is false means no radio button checked, add error in "err" 
if(re == false) err += '- You must check at least one vegetable';

// make "re" again False, and traverse the checkbox buttons
// if one is checked sets re to true, and stops the iteration with "break"
re = false
for(var i=0; i<frm.CMTEE_PREF_NEW.length; i++) {
  if(frm.CMTEE_PREF_NEW[i].checked) {
    re = true;
    break;
  }
}

// if "re" is false means no checkbox button checked, add error in "err" 
if (re == false) err += '\n - You must check at least one fruit';

// if "err" not empty, alert the error(s) and returns False to stop submitting form
if(err != "") {
  alert(err);
  return false;
}
else return re;
}
--></script>
<body>
<cfform id="f1" name="f1" action="confirmationn_e.cfm" method="POST">
<p><font size=4><strong>Fill out this form: </strong> </font></p>
<p><br>
  <label for="strEmail"><strong>1.</strong> If your skill set is suitable to other committees, </label>
</p>
<table border="0" cellspacing="0" cellpadding="0" width="100%" class="qtable">
<tr>
<td colspan="2" height="5" width="100%">
<cfoutput>
<input type="radio" name="contactme" id="contactme" value="Yes">
Yes &nbsp;
<input type="radio" name="contactme" id="contactme" value="No">
No<br>
</cfoutput>
<p><br>
  <label for="strEmail"><strong>2.</strong> Which of the following types of committee would you prefer to serve on?</label>
</p>
<table border="0" cellspacing="0" cellpadding="0" width="100%" class="qtable">
  <tr>
    <td colspan="2" height="5" width="100%"><input type="checkbox" name="CMTEE_PREF_NEW" id="CMTEE_PREF1" value="POL">
      POL <br>
      <input type="checkbox" name="CMTEE_PREF_NEW" id="CMTEE_PREF2" value="SOP">
      SOP <br>
      <input type="checkbox" name="CMTEE_PREF_NEW" id="CMTEE_PREF3" value="EE">
      EE<br />
      <input type="checkbox" name="CMTEE_PREF_NEW" id="CMTEE_PREF4" value="ADMIN" />
      ADMIN <br>
      <input type="checkbox" name="CMTEE_PREF_NEW" id="CMTEE_PREF5" value="TF">
      TF <br>
      <input type="checkbox" name="CMTEE_PREF_NEW" id="CMTEE_PREF6" value="ANY">
      ANY <br>
      <input type="checkbox" name="CMTEE_PREF_NEW" id="CMTEE_PREF7" value="SP">
      SP </td>
  </tr>
</table>
<p align="center">
  <input type="hidden" name="xaction" value="true">
  <input type="submit" value="Submit &raquo;" onclick="return checkButons(this.form);">
  &nbsp;&nbsp;
  <input type="reset" value="Reset" name="B2">
</p>
</cfform>
</body>
</html>

Open in new window


Tested on all browsers
As there are many ways to submit the form other than the button I would suggest moving the onclick back to onsubmit in the form tag. For instance pressing enter while in the email field will bypass the checking
The reason it doesn't work is your javascript code looks for checkboxes named "fruit", but your form fields are named "fruit1", "fruit2", etc...

Rather than rolling your own validation, I'd suggest using one of the many jquery libraries out there, such as http://jqueryvalidation.org/.

If you're only doing simple validation you could use the built-in cfform validation. It's not very robust, so I wouldn't recommend it for complex forms. But it's perfectly fine for simple validation like mandatory buttons and checkboxes:

<script type="text/javascript">
	function atLeastOneBoxSelected(frm, fld, value) {
		var boxes = document.getElementByName(fld.name)
		for (var i = 0; i < boxes.length; i++) {
			if (boxes[i].checked) {
				// valid if at least one box with this "name" was checked
				return true;	
			}	
		}
		// nothing was checked
		return false;
	}
</script>

<cfform action="" method="post" name="f1">
	<h4>Check a vegetable, and at least one fruit</h4>
	Vegetables: 
	  <cfinput type="radio" name="vegetable" value="cabbage"
			required="true"
			message="Please select a vegetable" />Cabbage
	  <cfinput type="radio" name="vegetable" value="carrot" />Carrot<br/>
	Fruits:<br/>
	 <!--- all boxes MUST have the same name --->
	 <cfinput type="checkbox" name="fruit" value="apple"
	        onValidate="atLeastOneBoxSelected"
			required="true"
			message="Please select at least one fruit" />Apple<br/>
	 <cfinput type="checkbox" name="fruit" value="pear" />Pear<br/>
	 <cfinput type="checkbox" name="fruit" value="banana" />Banana<br/>
	 Some optional setting:<br/>
		 <cfinput type="checkbox" name="test" value="foo" />Foo<br/>
		 <cfinput type="checkbox" name="test" value="bar" />Bar<br/>
	 
	 <input type="submit" value="Submit" />
</cfform>

Open in new window

Just be aware that setting the input types for checkboxes to the same name will mean you will overwrite one with another and only ONE value will be submitted.  This IS what you want for a radio group though as only one value is able to be selected.  What you should do is put them in an HTML array, like so:

Fruits:<br/>
      <input type="checkbox" name="fruit[]" value="apple" />Apple<br/>
      <input type="checkbox" name="fruit[]" value="pear" />Pear<br/>
      <input type="checkbox" name="fruit[]" value="banana" />Banana

Open in new window


Updated the jsbin (see link below).  It also allows for easy selection of your fruits like this:

 var fruits = document.getElementsByName("fruit[]");

Open in new window

http://jsbin.com/ILeBInE/2/edit
Just be aware that setting the input types for checkboxes to the same name will mean you will overwrite one with another and only ONE value will be submitted.  

Not exactly.  All of the values of whatever boxes you select will be submitted under the name "fruit"(Based on the error message and js code, that seems to be the goal here).

In CF, when the form is submitted, those values are automatically merged into a single FORM field containing a comma delimited list of whatever boxes you checked.  For example, if you check the 1st and 3rd "fruit" boxes, the field's value will be:

       FORM.fruit = "apple,banana"

> <input type="checkbox" name="fruit[]" value="banana" />Banana

(EDIT) Technically you don't need to use "[]".  Just using the same "name" - any name- for all of the checkboxes is what creates the array, not the "[]".
Interestingly, this would agree with what you're saying http://www.w3.org/TR/html401/interact/forms.html#checkbox

Obviously CF is following the rules.  I'm more a PHP man and I know If you coded this outside of CF it would not work, only the first input with that name would be seen in the POST'd data. example: http://phpfiddle.org/main/code/td9-usz

And in practice it doesn't work for PHP and my experience has been to always use the array markers [] to guarantee the values being posted.

Anyhow, this is CF we're dealing with but thought I should make the point.  

Ceratinly appreciate your comments @_agx_ and clarifying that.
Hey, I'm always up for learning more about how things are handled in other languages, so thanks for the heads up :)

Yeah, I know the behavior differs once you move from client side to server side handling. I'm not much of PHP person, but always liked the "[]" syntax. (CF has a lot of good features, but unfortunately was behind the curve on that one.  It didn't implement fields[] as arrays until CF10.)  Though it seems weird that PHP only returns a single value without the "[]".  The specs require that all of the values are submitted in the POST.  So to just drop the rest, and return only the 1st one, seems wrong.  I wonder how asp.net and other languages handle it? Just wondering if that behavior is in the majority.

> Just using the same "name" - any name- for all of the checkboxes is
> what creates the array, not the "[]".

EDIT:  BTW, for the archives .. I was referring to javascript with that comment. CF9 and earlier never create form field arrays. Only CF10 is capable of that - and only when the following setting is enabled:

        this.sameFormFieldsAsArray = true;
Cool! You read my mind. I was just about to post a similar question :)
@koila, now that we've sorted that array confusion (caused by me!) out.  Where are you at?
Avatar of koila

ASKER

According to Jim Horn, I've reviewed the script.  Your response wasn't corrected and helpful.

Thank you,