Check checkbox strange problem

M

morellik

Dear all,

I have a program that creates dinamically a web page.
In the page I have the following function to check how many checkbox
are checked.
function tarInfo(info) {
var i=0;
var c=0;
var l=document.forms[0].selected_files.length;
alert(l);
for (i=0; i<document.forms[0].selected_files.length;i++) {
if (document.forms[0].selected_files.checked) {
c++
}
}
..
..

The problem is that if I have only one checkbox, the alert(l) write
undefined. If I have more than 2 checkbox, the function works well.
Here a part of the webpage with one checkbox.

<form name="form1" action="filemanager" method="POST"
enctype="multipart/form-data" >
..
..
<td>
<input type="checkbox" value="pbsrun.o100"
name="selected_files">
</td>
..
..
<input type="submit" class="button" name="tar" value="Tar"
onClick="return tarInfo('tar')">

Where is the problem?
Thanks
Enrico
 
L

Lee

morellik said:
The problem is that if I have only one checkbox, the alert(l) write
undefined. If I have more than 2 checkbox, the function works well.

If there is only one checkbox, the form control is not an array,
and so has no length attribute. There are several possible ways
to handle this. You could check to see if the length is undefined
or, since you are generating the page, you could generate different
validation code depending on the number of checkboxes.


--
 
B

Bart Van der Donck

morellik said:
I have a program that creates dinamically a web page.
In the page I have the following function to check how many checkbox
are checked.
function tarInfo(info) {
var i=0;
var c=0;
var l=document.forms[0].selected_files.length;
alert(l);
for (i=0; i<document.forms[0].selected_files.length;i++) {
if (document.forms[0].selected_files.checked) {
c++
}
}
The problem is that if I have only one checkbox, the alert(l) write
undefined. If I have more than 2 checkbox, the function works well.
[...]


I think you have a small misunderstanding of how <input
type="checkbox"> works. You can't have more than one <input
type="checkbox"> with the same name-attribute in the same form, because
each checkbox is an object of its own (unlike <input type="radio">). It
would be just the same as saying:

<input type="text" name="password" value="abc">
<input type="text" name="password" value="123">

It's unpredictable how browsers react on this kind of constructions
when submitting the form or when scripting such elements. Changing your
HTML-code so that no 2 <input type="checkbox">'s hold the same name,
will probably solve your problem. Once that is okay, one can obtain the
number of checked boxes by doing:

<form>
<input type="checkbox" value="v1" name="c1">
<input type="checkbox" value="v2" name="c2">
<input type="checkbox" value="v3" name="c3">
<input type="checkbox" value="v4" name="c4">
<input type="button" value="check" onClick="check_boxes()">
</form>
<script type="text/javascript">
function check_boxes() {
var c = 0
for (var i=0; i<document.forms[0].length; i++) {
if (document.forms[0].elements.type =='checkbox') {
if (document.forms[0].elements.checked) {
c++
}
}
}
alert(c + ' checkboxes are checked in forms[0]')
}
</script>

Hope this helps,
 
A

ASM

morellik a écrit :
Dear all,

I have a program that creates dinamically a web page.
In the page I have the following function to check how many checkbox
are checked.
function tarInfo(info) {
var i=0;
var c=0;

var l = document.forms[0].selected_files;
l = l.length? l.length : 0;
alert(l);
if(l>0)
for (i=0; i<document.forms[0].selected_files.length;i++)
if (document.forms[0].selected_files.checked) c++;


else
if (document.forms[0].selected_files.checked) c=1;
}
The problem is that if I have only one checkbox, the alert(l) write
undefined. If I have more than 2 checkbox, the function works well.

Other way :

function tarInfo(info)
{
var c=0;
var l = info.elements;
for(var i=0; i<l.length; i++)
if(
l.type=='checkbox' &&
l.name.indexOf('selected_files')==0 &&
l.checked
)
c++;
return confirm('You have selected : '+c+' file(s)\nIs it OK?');
}

<form name="form1" action="filemanager" method="POST"
enctype="multipart/form-data" onsubmit="return tarInfo(this);">

<p>File 0100 :
<input name="selected_files[0]" type="checkbox" value="pbsrun.o100">
<p>File 0200 :
<input name="selected_files[1]" type="checkbox" value="pbsrun.o200">
<p>File 0300 :
<input name="selected_files[2]" type="checkbox" value="pbsrun.o300">
<p>File 0400 :
<input name="selected_files[3]" type="checkbox" value="pbsrun.o400">

<input type="submit" class="button" name="tar" value="Tar">
</form>
 
L

Lee

Bart Van der Donck said:
I have a program that creates dinamically a web page.
In the page I have the following function to check how many checkbox
are checked.
function tarInfo(info) {
var i=0;
var c=0;
var l=document.forms[0].selected_files.length;
alert(l);
for (i=0; i<document.forms[0].selected_files.length;i++) {
if (document.forms[0].selected_files.checked) {
c++
}
}
The problem is that if I have only one checkbox, the alert(l) write
undefined. If I have more than 2 checkbox, the function works well.
[...]


I think you have a small misunderstanding of how <input
type="checkbox"> works. You can't have more than one <input
type="checkbox"> with the same name-attribute in the same form, because
each checkbox is an object of its own (unlike <input type="radio">).


The understanding is yours.
Form controls that share the same NAME attribute are treated as an array.


--
 
B

Bart Van der Donck

ASM said:
function tarInfo(info)
{
var c=0;
var l = info.elements;
for(var i=0; i<l.length; i++)
if(
l.type=='checkbox' &&
l.name.indexOf('selected_files')==0 &&
l.checked
)
c++;
return confirm('You have selected : '+c+' file(s)\nIs it OK?');
}

<form name="form1" action="filemanager" method="POST"
enctype="multipart/form-data" onsubmit="return tarInfo(this);">

<p>File 0100 :
<input name="selected_files[0]" type="checkbox" value="pbsrun.o100">
<p>File 0200 :
<input name="selected_files[1]" type="checkbox" value="pbsrun.o200">
<p>File 0300 :
<input name="selected_files[2]" type="checkbox" value="pbsrun.o300">
<p>File 0400 :
<input name="selected_files[3]" type="checkbox" value="pbsrun.o400">

<input type="submit" class="button" name="tar" value="Tar">
</form>


Your code is rather infirm IMHO. By naming your checkboxes
selected_files[0] to selected_files[3], you seem to create the
impression that they belong to a same array, which is not the case. I
would even counsel to use only alphanumericals (+underscore) as
elements names in the first place. Also, I think the line where you say
l.checked is to be avoided. Only checkboxes can be ".checked" or
not, but all other form elements pass your for-loop as well. But yes,
IE & FF do not seem to bark at that (though I had expected they would
have).
 
A

ASM

Bart Van der Donck a écrit :
ASM said:
function tarInfo(info)
{
var c=0;
var l = info.elements;
for(var i=0; i<l.length; i++)
if(
l.type=='checkbox' &&
l.name.indexOf('selected_files')==0 &&
l.checked
)
c++;
return confirm('You have selected : '+c+' file(s)\nIs it OK?');
}

<form name="form1" action="filemanager" method="POST"
enctype="multipart/form-data" onsubmit="return tarInfo(this);">

<p>File 0100 :
<input name="selected_files[0]" type="checkbox" value="pbsrun.o100">
<p>File 0200 :
<input name="selected_files[1]" type="checkbox" value="pbsrun.o200">
<p>File 0300 :
<input name="selected_files[2]" type="checkbox" value="pbsrun.o300">

<input type="submit" class="button" name="tar" value="Tar">
</form>


Your code is rather infirm IMHO. By naming your checkboxes
selected_files[0] to selected_files[3], you seem to create the
impression that they belong to a same array, which is not the case.


I did see that after having posted, it is not very important in what I
wanted to show, OP can even keep the unique name he has chosen.
Also, I think the line where you say
l.checked is to be avoided.


Isn't it what we search ? (checked checkboxes)
Only checkboxes can be ".checked" or
not,

and radio-buttons too :)
but all other form elements pass your for-loop as well. But yes,
IE & FF do not seem to bark at that (though I had expected they would
have).

Of course :
as soon as
l.type=='checkbox'
returns false, next conditions aren't read by JS parser.

if it returns true
then we see if the checkbox name begins with correct string
then we verify if it is checked
 
B

Bart Van der Donck

Lee said:
Bart Van der Donck said:


The understanding is yours.
Form controls that share the same NAME attribute are treated as an array.

You're right.

var d = 0;
if (document.forms[0].elements['c'].length)
{
for (var i=0; i<document.forms[0].elements['c'].length; ++i) {
if (document.forms[0].elements['c'].checked) ++d;
}
}
else
{
if (document.forms[0].elements['c'].checked) ++d;
}
alert(d + ' checkboxes are checked in forms[0]')

should always work (for single/multiple checkboxes named "c" in this
case).
 
B

Bart Van der Donck

ASM said:
Bart Van der Donck a écrit :
ASM said:
function tarInfo(info)
{
var c=0;
var l = info.elements;
for(var i=0; i<l.length; i++)
if(
l.type=='checkbox' &&
l.name.indexOf('selected_files')==0 &&
l.checked
)
c++;
return confirm('You have selected : '+c+' file(s)\nIs it OK?');
}

<form name="form1" action="filemanager" method="POST"
enctype="multipart/form-data" onsubmit="return tarInfo(this);">

<p>File 0100 :
<input name="selected_files[0]" type="checkbox" value="pbsrun.o100">
<p>File 0200 :
<input name="selected_files[1]" type="checkbox" value="pbsrun.o200">
<p>File 0300 :
<input name="selected_files[2]" type="checkbox" value="pbsrun.o300">

<input type="submit" class="button" name="tar" value="Tar">
</form>


Your code is rather infirm IMHO. By naming your checkboxes
selected_files[0] to selected_files[3], you seem to create the
impression that they belong to a same array, which is not the case.


I did see that after having posted, it is not very important in what I
wanted to show, OP can even keep the unique name he has chosen.


Yes, but one could easily get into trouble with constructions like
document.forms[0].selected_files[0].value
(with selected_files[0] being thought of as the actual name-argument,
for instance)
Also, I think the line where you say
l.checked is to be avoided.


Isn't it what we search ? (checked checkboxes)


Yes (see below).
and radio-buttons too :)

Right. I thought of ".selected" for radios when I wrote that.
but all other form elements pass your for-loop as well. But yes,
IE & FF do not seem to bark at that (though I had expected they would
have).

Of course :
as soon as
l.type=='checkbox'
returns false, next conditions aren't read by JS parser.

if it returns true
then we see if the checkbox name begins with correct string
then we verify if it is checked


Indeed, now I remember again that the circuit is left at the first
non-match with '&&' and at the first match with '||'. Didn't think that
far!
 
B

Bart Van der Donck

Bart said:
Right. I thought of ".selected" for radios when I wrote that.

Some further thoughts about this obvious mistake. Actually I think that
".selected" would be a more intuitive syntax for radios than
".checked". The former seems to involve a sort of list where one can
pick out an item, like chosen from a group such as e.g. a person that
is selected for a job so. The latter makes me rather think of a boolean
flag (yes/no) on a strict per-element base that has nothing to do with
anything else in the form. Of course each radio can be thought of as
boolean as well, but not in the same sense as a checkbox (which is
"more boolean" in that regard). Therefore I believe that radios have
more in common with <select>s than with checkboxes. In that view, it
would be linguistically more logic to think of ".selected" rather than
".checked" for radios.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top