Forum Moderators: open

Message Too Old, No Replies

Multiple checkbox arrays for PHP and JS control

         

Craig79

4:01 pm on Feb 13, 2006 (gmt 0)

10+ Year Member



I saw other posts about a single group of checkboxes, but nothing to cover multiple groups of checkboxes.

There are going to be multiple groups of checkboxes on a single form. A checkbox group consists of an "Any" checkbox, followed by several other checkboxes. The problem is that I need to pass the checkbox groups as an array for PHP processing, so I would need to have color[] and make[], but the JS doesn't like this.

Thanks in advance! Here is the code, which currently works:

<html>
<head>
<title></title>
<script language=javascript>
<!--
function CheckAny(refControlArray,strAny,me){
var formIndex;
var controlMax = refControlArray.length
for (formIndex = 0; formIndex < controlMax; formIndex++){
if (refControlArray[formIndex].value==strAny){
refControlArray[formIndex].checked = true;
} else {
refControlArray[formIndex].checked = false;
}
}
}

function UnCheckAny(refControlArray,strAny,me){
var formIndex;
var controlMax = refControlArray.length
for (formIndex = 0; formIndex < controlMax; formIndex++){
if (refControlArray[formIndex].value==strAny){
refControlArray[formIndex].checked = false;
}
}
}
-->
</script>
</head>

<body>
<form name=myform method=post action=#>

<INPUT type=checkbox name=colors onclick=CheckAny(this.form.colors,'100',this) value="100">
Any<p>

<input type=checkbox name=colors onclick=UnCheckAny(this.form.colors,'100',this) value="1">
Blue<br>

<input type=checkbox name=colors onclick=UnCheckAny(this.form.colors,'100',this) value="2">
Green<br>

<input type=checkbox name=colors onclick=UnCheckAny(this.form.colors,'100',this) value="3">
Red<br>

<hr>
<p>

<INPUT type=checkbox name=make onclick=CheckAny(this.form.make,'200',this) value="200">
Any<p>

<input type=checkbox name=make onclick=UnCheckAny(this.form.make,'200',this) value="1">
Ford<br>

<input type=checkbox name=make onclick=UnCheckAny(this.form.make,'200',this) value="2">
Chevy<br>

<input type=checkbox name=make onclick=UnCheckAny(this.form.make,'200',this) value="3">
Nissan<br>

<input type=checkbox name=make onclick=UnCheckAny(this.form.make,'200',this) value="4">
Honda<br>

</form>
</body>
</html>

Bernard Marx

4:06 pm on Feb 13, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



A common question, Craig.

Here's the common answer:

this.form["colors[]"]

since:

obj.prop == obj["prop"]

..much like PHP, I believe.

-------------

..and WELCOME!

Craig79

4:16 pm on Feb 13, 2006 (gmt 0)

10+ Year Member



I just tried that but the checkboxes don't function properly - if you check the "Any" box while a box below it is checked, it should remove the checks from all boxes under the "Any" box. What am I doing wrong?
Thanks!

Bernard Marx

4:54 pm on Feb 13, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



<html> 
<head>
<title></title>
<script language=javascript>

function checkClicked(refControl)
{
var elms = refControl.form.elements[refControl.name];
/* Was clicked 1st elm? */
if(refControl == elms[0])
for(var k=1; k<elms.length; k++)
elms[k].checked = false;
else
elms[0].checked = false;
}
</script>
</head>

<body>
<form name=myform method=post action=# onclick="checkClicked(event)">
<input type=checkbox name="colors[]" onclick=checkClicked(this) value="100">Any<p>
<input type=checkbox name="colors[]" onclick=checkClicked(this) value="1">Blue<br>
<input type=checkbox name="colors[]" onclick=checkClicked(this) value="2">Green<br>
<input type=checkbox name="colors[]" onclick=checkClicked(this) value="3">Red<br>
<p>
<hr>
<input type=checkbox name="make[]" onclick=checkClicked(this) value="200">Any<p>
<input type=checkbox name="make[]" onclick=checkClicked(this) value="1">Ford<br>
<input type=checkbox name="make[]" onclick=checkClicked(this) value="2">Chevy<br>
<input type=checkbox name="make[]" onclick=checkClicked(this) value="3">Nissan<br>
<input type=checkbox name="make[]" onclick=checkClicked(this) value="4">Honda<br>
</form>
</body>
</html>

[edited by: DrDoc at 4:58 pm (utc) on Feb. 13, 2006]
[edit reason] tpyo [/edit]

Bernard Marx

5:00 pm on Feb 13, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Toyp? :)

Craig79

5:11 pm on Feb 13, 2006 (gmt 0)

10+ Year Member



WOW!

That works great! There is a JS error that says:

'form.elements is null or not an object'

but it does work!
Thanks so much!

Bernard Marx

7:45 pm on Feb 13, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



That works great! There is a JS error that says: ..

Hmmm. Yes, sorry, I started to try another approach, and left some of it in there.

To get rid of the error, remove the:

[blue]onclick="checkClicked(event)"[/blue]
from the form element.

Alternatively, you could

1) Leave the event handler on the form.

2) Amend the top of the function to look like this:


/* change corrupted [b][red]¦¦[/red][/b] chars for pipes */
function formClicked(e)
{
var refControl = e.target[red]¦¦[/red]e.srcElement;
if(refControl.type!= "checkbox") return true;
var elms = refControl.form.elements[refControl.name];
...etc...


3) Remove all those messy event handlers on the checkboxes.

Craig79

8:37 pm on Feb 13, 2006 (gmt 0)

10+ Year Member



yep, that did it.
Thanks very much!

Craig79

10:11 pm on Feb 13, 2006 (gmt 0)

10+ Year Member



I went with the first option and removed the event handler from the FORM line.

Since you were great at the last question, could you answer 1 more?

What if there was a 3rd set of 7 checkboxes, with no "Any" master box over them, and I wanted to limit the selection to 2 boxes? If they tried to click on a 3rd one, an alert would pop up and would not let the 3rd be selected.

Thanks!

Bernard Marx

11:45 pm on Feb 13, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



<html>
<head>
<title>Test</title>
<style type="text/css">
body{font: x-small verdana;}
#thingsNote{width: 200px; margin: 0; border: solid 1px white;}
.flash{ background: #FFCCFF;border-color:red; }
</style>
<script language=javascript>

/*--------------------------------------------
Map of baseNames to max choices
--------------------------------------------*/
var restricted =
{
thing: 2,
stuff: 3
}
/*--------------------------------------------
An event-based scheme needs a little more
groundwork if it's going to start getting
complicated. A single listening function
can get a little serpentine
..but this will do.
--------------------------------------------*/
function formClicked(e)
{
var refControl = e.target¦¦e.srcElement;
if(refControl.type!= "checkbox") return;
var refName = refControl.name;
var refForm = refControl.form;
var elms = refForm.elements[refName];
var k, elm, max, baseName;
/*----------------------------------------
changed: (see HTML)
className includes class, "any"
----------------------------------------*/
if(/\bany\b/.test(refControl.className) )
{
for(k=1; k<elms.length; k++)
elms[k].checked = false;
}
else
{
/*----------------------------------------
Is restricted
----------------------------------------*/
baseName = refControl.name.replace("[]","");
max = restricted[baseName];
if(max)
{
/* get no of checked, as length of vals array */
if(getCheckGroupValues(refForm, refName).length > max)
{
refControl.checked = false;
showError(baseName);
}
}
/*----------------------------------------
Not restricted
----------------------------------------*/
else
elms[0].checked = false;
}
}

/*--------------------------------------------
General fn: Returns more info than req'd
- but useful anyway.
--------------------------------------------*/
function getCheckGroupValues(form, name)
{
var arr=[], elms=form.elements[name];
for(var k=-1,elm;elm=elms[++k];)
if(elm.checked)
arr[arr.length]=elm.value;
return arr;
}

/*--------------------------------------------
Not keen on alerts, so I did this for
a laugh. You can replace the function call
with an alert, or place an alert at the top
of this function - so getting both.

An alert may be more suited to the visually
impaired (I think).
--------------------------------------------*/
function showError(id)
{
var elm = document.getElementById(id);
var nFlashes = 6;/* even */
var isFlash = false;
var timer = setInterval(flash, 500);
function flash()
{
nFlashes--
? elm.className = (isFlash=!isFlash)?"flash":""
: clearTimeout(timer);
}
}

</script>
</head>
<body>
<form name=myform method=post action=# onclick="formClicked(event)">
<input type=checkbox name="colors[]" value="100" class="any">Any<br><br>
<input type=checkbox name="colors[]" value="1">Blue<br>
<input type=checkbox name="colors[]" value="2">Green<br>
<input type=checkbox name="colors[]" value="3">Red<br>
<hr>
<input type=checkbox name="make[]" value="200" class="any">Any<br><br>
<input type=checkbox name="make[]" value="1">Ford<br>
<input type=checkbox name="make[]" value="2">Chevy<br>
<input type=checkbox name="make[]" value="3">Nissan<br>
<input type=checkbox name="make[]" value="4">Honda<br>
<hr>
<p id="thing">Select no more than <b>2</b> from below:</p>
<input type=checkbox name="thing[]" value="1">Thing 1<br>
<input type=checkbox name="thing[]" value="2">Thing 2<br>
<input type=checkbox name="thing[]" value="3">Thing 3<br>
<input type=checkbox name="thing[]" value="4">Thing 4<br>
<input type=checkbox name="thing[]" value="5">Thing 5<br>
<hr>
<p id="stuff">Select no more than <b>3</b> from below:</p>
<input type=checkbox name="stuff[]" value="1">Stuff 1<br>
<input type=checkbox name="stuff[]" value="2">Stuff 2<br>
<input type=checkbox name="stuff[]" value="3">Stuff 3<br>
<input type=checkbox name="stuff[]" value="4">Stuff 4<br>
<input type=checkbox name="stuff[]" value="5">Stuff 5<br>
</form>
</body>
</html>

Craig79

12:25 am on Feb 14, 2006 (gmt 0)

10+ Year Member



That's over and above with the cool flashes, and it all works great!

Thanks very much!