Need Javascript code to limit form checkbox selection

Hello,

Take a look at the code below. I need a Javascript code that will check the checkbox selection for each question. I’ve searched the Internet and found many Javascript code that only checks one question. But I need a code that can do the check for multiple questions. Each question should have a different max selection. Like Question 1 can have max 2 selection, question 2 can have max 4 selections. Any one can show me the way to this?


<br>Question 1:
<input type="checkbox" name="answer[148][]" value="761" id="60833.148.761" /> <label for="60833.148.761">Answer 1</label><br />
<input type="checkbox" name="answer[148][]" value="762" id="60833.148.762" /> <label for="60833.148.762">Answer 2</label><br />
<input type="checkbox" name="answer[148][]" value="922" id="60833.148.922" /> <label for="60833.148.922">Answer 3</label><br />
<input type="checkbox" name="answer[148][]" value="923" id="60833.148.923" /> <label for="60833.148.923">Answer 4</label><br />
<input type="checkbox" name="answer[148][]" value="924" id="60833.148.924" /> <label for="60833.148.924">Answer 5</label><br />
<input type="checkbox" name="answer[148][]" value="925" id="60833.148.925" /> <label for="60833.148.925">Answer 6</label><br />
<br>Question 2:
<input type="checkbox" name="answer[193][]" value="926" id="60833.193.926" /> <label for="60833.193.926">Answer 1</label><br />
<input type="checkbox" name="answer[193][]" value="927" id="60833.193.927" /> <label for="60833.193.927">Answer 2</label><br />
<input type="checkbox" name="answer[193][]" value="928" id="60833.193.928" /> <label for="60833.193.928">Answer 3</label><br />
<input type="checkbox" name="answer[193][]" value="929" id="60833.193.929" /> <label for="60833.193.929">Answer 4</label><br />
<input type="checkbox" name="answer[193][]" value="930" id="60833.193.930" /> <label for="60833.193.930">Answer 5</label><br />
<input type="checkbox" name="answer[193][]" value="931" id="60833.193.931" /> <label for="60833.193.931">Answer 6</label><br />

What you want to do is pretty straight forward.

So are you looking to learn how to do it or are you looking for someone to just post the code? If you are looking to learn how to do it, then post the javascript you have so far and we can try to help you get it working. If you want someone to just post the code, then hopefully someone else will come along.

This is the code that I have so far. Please check if it’s a correct code. Will it work on all browsers? Can it be shorter than that?


<script type="text/javascript">
function limit_checkbox(name,obj,max)
   {
   var count=0;
   var x=document.getElementsByName(name);
   for (var i=0; i < x.length; i++)
      {
      if(x[i].checked)
	     {
         count = count + 1;
		 }
	  }	
   if (count > max)
	  {
	  alert('Please select only ' + max + ' checkboxes.\
To select this option unselect one of the others.');
	  obj.checked = false;
      }
   }
</script>

<br>Question 1:
<input type="checkbox" name="answer[148][]" value="761" id="60833.148.761" onclick="limit_checkbox('answer[148][]',this,2)" /> <label for="60833.148.761">Answer 1</label><br />
<input type="checkbox" name="answer[148][]" value="762" id="60833.148.762" onclick="limit_checkbox('answer[148][]',this,2)" /> <label for="60833.148.762">Answer 2</label><br />
<input type="checkbox" name="answer[148][]" value="922" id="60833.148.922" onclick="limit_checkbox('answer[148][]',this,2)" /> <label for="60833.148.922">Answer 3</label><br />
<input type="checkbox" name="answer[148][]" value="923" id="60833.148.923" onclick="limit_checkbox('answer[148][]',this,2)" /> <label for="60833.148.923">Answer 4</label><br />
<input type="checkbox" name="answer[148][]" value="924" id="60833.148.924" onclick="limit_checkbox('answer[148][]',this,2)" /> <label for="60833.148.924">Answer 5</label><br />
<input type="checkbox" name="answer[148][]" value="925" id="60833.148.925" onclick="limit_checkbox('answer[148][]',this,2)" /> <label for="60833.148.925">Answer 6</label><br />
<br>Question 2:
<input type="checkbox" name="answer[193][]" value="926" id="60833.193.926" onclick="limit_checkbox('answer[193][]',this,3)" /> <label for="60833.193.926">Answer 1</label><br />
<input type="checkbox" name="answer[193][]" value="927" id="60833.193.927" onclick="limit_checkbox('answer[193][]',this,3)" /> <label for="60833.193.927">Answer 2</label><br />
<input type="checkbox" name="answer[193][]" value="928" id="60833.193.928" onclick="limit_checkbox('answer[193][]',this,3)" /> <label for="60833.193.928">Answer 3</label><br />
<input type="checkbox" name="answer[193][]" value="929" id="60833.193.929" onclick="limit_checkbox('answer[193][]',this,3)" /> <label for="60833.193.929">Answer 4</label><br />
<input type="checkbox" name="answer[193][]" value="930" id="60833.193.930" onclick="limit_checkbox('answer[193][]',this,3)" /> <label for="60833.193.930">Answer 5</label><br />
<input type="checkbox" name="answer[193][]" value="931" id="60833.193.931" onclick="limit_checkbox('answer[193][]',this,3)" /> <label for="60833.193.931">Answer 6</label><br />

Did everything work as it should when you ran it?

If not, what error messages did you get and what didn’t work as it should?

I wonder what ever happened to this forum. In the old days people were eager to help you out. When you ask a question they answer you, when you don’t know something they point you in the right direction (webpage or piece of code), when you post your code they give you feedback on your code. No matter how stupid your question was, there was always someone willing to answer you and help you out. I couldn’t have created my websites without the help of this forum. Now it seems that people just answer your question with another question. But I guess that was then, this is now. I sure miss the old good days though.

But nowadays a lot more people treat forums as a “free code debugging service”.

They just simply dump code in a post and ask someone to check it for them.

I asked you a simple question. It’s quicker for me for you to tell me if your code worked as you expect when you ran it, than it is for me to copy and paste it into a file and run it.

It sounds like you didn’t even run the code you posted.

Let’s return back to the good old days.

The code you posted seems to do the job you want, so let’s go through some improvements.

First is to clean up the HTML code by removing the inline HTML onclick events, and by wrapping the label around the input field so that you don’t need to provide an explicit association.


<label><input type="checkbox" name="answer[148][]" value="761" /> Answer 1</label><br />

Breaks should not be used either really. They are only to be used for poetry or for separating lines of an address.
Instead of breaks you should use other appropriate form elements, such as list or paragraphs, and use CSS to style the presentation of things as is appropriate.

Now that the inline html onclick attributes have been culled from the HTML, we should apply them instead from the script code. This can be easily done by moving the script code to the end of the body, just before the </body> tag so that the script can easily work with elements on the page before the page finishes loading.


<body>
    ...
    <script type="text/javascript" src="js/checkboxLimit.js></script>
</body>

We can have the script automatically get the required limit for each checkbox group, from a config variable, which could be in the following sort of manner:


var checkboxConfig = [
    {name: 'answer[148][]', limit: 2},
    {name: 'answer[193][]', limit: 3}
];

That checkboxConfig is something that your server-side script (PHP or something else) can write to the HTML page as a separate piece of script. With the rest of the code below in a separate file, this is how the structure of your code would look like:


<body>
    ...
    <script type="text/javascript">
    var checkboxConfig = [
        {name: 'answer[148][]', limit: 2},
        {name: 'answer[193][]', limit: 3}
    ];
    </script>
    <script type="text/javascript" src="js/checkboxLimit.js"></script>
</body>

The script in the script file wouldn’t need to be changed then. It can just get what it needs from that checkboxConfig variable.


var i;
for (i = 0; i < checkboxConfig.length; i += 1) {
    setLimit(checkboxConfig[i].name, checkboxConfig[i].limit);
}

Now it’s easy to adjust the config object with the appropriate settings. If need be, you can remove that config variable from the script file and have PHP write an appropriate config assignment as an earlier script piece, so that the script file doesn’t need to be changed at all, only the config piece itself.

Setting the limit it just a matter of looping through all elements that match the name, and assign a click handler to each one.


function setLimit(name, limit) {
    var els = document.getElementsByName(name),
        i;
    for (i = 0; i < els.length; i += 1) {
        els[i].onclick = checkboxClickHandler(els[i], limit);
    }
}

There were a couple of options with the click handler. You can use closure to attach variables to functions (such as the limit) so that a no argument function can be called that still has access to the limit, but in this case I went with a simpler option of using a new function for each click handler instead. Keep in mind though that with large projects, you may want to reduce the number of event functions, in which case using closure results in some memory-saving benefits.


function checkboxClickHandler(el, limit) {
    return function () {
        limit_checkbox(el, limit);
    }
}

I’m only using two variables for the function there, because the name can be easily retrieved from the element itself, so there’s no need to pass the name as a separate parameter to the function.

Here’s that limitCheckbox function that you had, with some adjustments made to it for the sake of clarity, such as using more expressive variable names than “obj”



function limitCheckbox(el, max) {
    var count = 0,
        i;
    var checkboxes = document.getElementsByName(el.name);
    for (i = 0; i < checkboxes.length; i += 1) {
        if (checkboxes[i].checked) {
            count = count + 1;
		}
	}	 
    if (count > max) {
	    alert('Please select only ' + max + ' checkboxes.\
To select this option unselect one of the others.');
	    el.checked = false;
    }
}

With that, all you need to do is to add other names and limits to the checkboxConfig variable, and you’re all set.

Paul,

Thanks for your feedback. That’s what I’m talking about. People taking a look at your code and giving you tips for improvements. You joined the forum in 2007 so you probably experienced some of the old good days. So you know how it’s done. :wink:

First of all, I didn’t know that you can use the label tag like that. That will help me clean my HTML code. The Javascript codes that you wrote seems complicated. But I will sure take a look at them. I also appreciate your adjustments my code. Thanks again!

Then next time ask for feedback or at least be more descriptive in what you are after.

When you say

This is the code that I have so far. Please check if it’s a correct code.

that to me, and I suspect many others as well, just says ‘here is my code. can you run it and fix it for me’ - well at least you said “please” :).

Like I said, many people treat forums as a free coding and debugging service which I don’t do for free. If you’re more descriptive in your requests it can only improve the chances of more people replying, otherwise you just have to wait and twiddle your thumbs waiting for a reply to hopefully come from however many forums you have posted your request on.