I'm using classic ASP here, and trying to do some Javascript validation.

In my form, I'm dynamically creating checkbox groups - each group has a common Name, and each checkbox has a unique ID. Before the form submits (in the onclick on the submit button) I want to check and make sure each checkbox group has at least one of it's checkboxes checked. If that makes sense :-)

I guess I'm conceptually running into problems. I think I want to, on submit, loop through all of the checkbox Names, and make sure at least one item is checked out of each of those Name groups. Can this be done? This is what I have so far, but I think it's getting thrown off by using the ID instead of the Name:

function validateCheckBox()
{
	var checkSelected = false;
	var checkboxid
	
	for(i=0; i<document.frmEditCoverages.elements.length; i++)
	{
		if(document.frmEditCoverages.elements[i].type=="checkbox")
		{
			/*need to do this for each checkbox on the page*/
			checkboxid = document.frmEditCoverages.elements[i]; 
			for (i = 0;  i < checkboxid.length;  i++){
			  if (checkboxid[i].checked){
			    checkSelected = true;
			  }
			}
			if (!checkSelected){
			  alert("WARNING MESSAGE TELLING THEM TO CHECK A CHECKBOX.");
			  return (false);
			}	
		}		
	}

}

Any help or advice? Thanks!

Dani AI

Generated

Short version: group checkboxes by their name, validate on the form's submit event (not the submit button's onclick), and avoid reusing the same loop index variable inside nested loops — that was the bug in your original code. was right that your handler must allow submission on success, and 's object-mapping approach is a solid pattern. Below is a concise alternative that uses CSS selectors to test each name-group and focuses the first offending control.

// returns true when every checkbox-name group has at least one checked box
function validateCheckboxGroups(form) {
  var boxes = form.querySelectorAll('input[type=checkbox][name]');
  var names = {};
  for (var i = 0; i < boxes.length; i++) {
    names[boxes[i].name] = true;
  }

  for (var name in names) {
    if (!form.querySelector('input[name="' + name + '"]:checked')) {
      var first = form.querySelector('input[name="' + name + '"]');
      if (first && typeof first.focus === 'function') first.focus();
      alert('Please select at least one option from "' + name + '".');
      return false;
    }
  }
  return true;
}

// hookup example: validate on submit so Enter/key-based submits are caught
document.getElementById('frmEditCoverages')
  .addEventListener('submit', function (e) {
    if (!validateCheckboxGroups(this)) e.preventDefault();
  });

Notes and gotchas: if a group name contains special characters use CSS.escape(name) or fall back to inspecting form.elements[name] (it may be a single Element or a collection depending on the browser). Also prefer validating on submit so other submit paths are handled. For selector details and the checked property, see the MDN docs: Document.querySelectorAll and HTMLInputElement.checked.

Recommended Answers

All 3 Replies

Shouldn't you return a value of true if a box is selected?

Also, you are returning before you check all of the boxes.

Well, yeah, I probably need to return checkSelected or something. Errrrr, actually, it probably would work if it popped the warning for each one, and then returned for that one. Ideally I'd focus on that element so they can select it. But shouldn't the FOR loop through all the elements hit all the checkboxes?

I guess what I want to do is loop through all of the checkboxes on the page, but name instead of ID so I can get the groups of checkboxes. And if at least one box isn't checked for each group, I want to pop the message. Sigh....I shouldn't be struggling with this as much as I am :-/ I'll try breaking it down some more and see what I can do...

You need to have a basic understanding of Javascript objects for understanding the solution presented below:

Test.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/2002/REC-xhtml1-20020801/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<link rel = "stylesheet" href = "Styles.css" media = "all" type = "text/css" />
<title>sample page</title>
</head>
<body id = "myBody">
    <noscript>Your browser doesn't support javascript. Be prepared for broken site functionality...</noscript>
    <form id = "myForm" action = "">
    <div id = "myDiv">
        <fieldset>
        <legend>First</legend>
        <input type = "checkbox" name = "first" id = "first" value = "1" /><label for = "first">One</label><br />
        <input type = "checkbox" name = "first" id = "second" value = "2" /><label for = "second">Two</label><br />
        <input type = "checkbox" name = "first" id = "third" value = "3" /><label for = "third">Three</label><br />
        </fieldset>
        <br /><br />
        
        <fieldset>
        <legend>Second</legend>
        <input type = "checkbox" name = "second" id = "four" value = "4" /><label for = "four">Four</label><br />
        <input type = "checkbox" name = "second" id = "five" value = "5" /><label for = "five">Five</label><br />
        </fieldset>
        <br /><br />
        
        <fieldset>
        <legend>Third</legend>
        <input type = "checkbox" name = "third" id = "six" value = "6" /><label for = "six">Six</label><br />
        <input type = "checkbox" name = "third" id = "seven" value = "7" /><label for = "seven">Seven</label><br />
        </fieldset>
        <br /><br />        
    </div>
    <input type = "submit" value = "Check validity" id = "btn" onclick = "SOS.validate('myDiv');" />
    </form>
<script type = "text/javascript" src = "Lib.js"></script>
</body>
</html>

var SOS = 
{
    validate : function(id)
    {
        var obj = {};
        var element = null;
        var myDiv = document.getElementById(id);
        var elements = myDiv.getElementsByTagName('input');
        
        for(var i = 0, limit = elements.length; i < limit; ++i)
        {
            element = elements[i];
            obj[element.name] = !!(obj[element.name] || element.checked);
        }
        
        for(var prop in obj)
        {
            if(obj[prop] == false)
            {
                alert('Check at least one box in the group ' + prop.toUpperCase());
                return(false);
            }
        }
        alert('Form successfully submitted');
        return(true);
    }
}

Styles.css

#myDiv
{
    width: 20%;
}
#myDiv legend
{
    color: #ababab;
    font-weight: bold;
}

#myDiv fieldset
{
    background-color: #efefef;
}

#btn
{
    border: 1px #aabbcc solid;
}
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.