HELP - select all checkbox javascript works fine.. unless there is only one checkbox.

M

Michael Champagne

We have an application to where you can select/deselect all checkboxes
in a checkbox array by clicking a 'master' checkbox at the top of the
screen. This seems to work fine unless there is only one checkbox
(these are dynamically generated). Why does this fail? If I do an
alert(field_to_check.length) with 1 element in the array like this I
get 'Undefined'. Is this because this datatype is not an array if
there is only 1 element here? Thanks for any responses.

The function that checks the checkboxes is:

function check(this_field, field_to_check)
{
var i;
if (eval(this_field.checked))
{
for(i=0; i<field_to_check.length;i++)
field_to_check.checked=true;
return 1;
}
else
{
for(i=0; i<field_to_check.length;i++)
field_to_check.checked=false;
return 0;
}
}

The onClick event to this function is:
<input type='checkbox' name='check_all' value=1 checked
onClick="check(this,
this.form.elements['acct_num_list[]']);">

And the array of checkboxes when there is 1 element in them is:
<input class='copy' type='checkbox' name="acct_num_list[]"
value='something' checked>

Mike
 
M

Matt Kruse

Michael Champagne said:
Is this because this datatype is not an array if
there is only 1 element here?

That's correct. So you need to check whether or not your object reference is
an array first, and treat it differently.
You can test if it's an array of checkboxes with something like:
function isCheckboxArray(obj) {
return ((typeof
obj.type!="string")&&(obj.length>0)&&(obj[0]!=null)&&(obj[0].type=="checkbox
"));
}

Also, I have a library which handles "checkbox groups" like this, including
this situation and others you may not have considered. You can check it out
at http://www.mattkruse.com/javascript/checkboxgroup/ if you wish!
 
M

Michael Winter

We have an application to where you can select/deselect all checkboxes
in a checkbox array by clicking a 'master' checkbox at the top of the
screen. This seems to work fine unless there is only one checkbox
(these are dynamically generated). Why does this fail? If I do an
alert(field_to_check.length) with 1 element in the array like this I
get 'Undefined'. Is this because this datatype is not an array if
there is only 1 element here? Thanks for any responses.

The function that checks the checkboxes is:

function check(this_field, field_to_check)
{
var i;
if (eval(this_field.checked))

This eval() call is *really* not needed.
{
for(i=0; i<field_to_check.length;i++)
field_to_check.checked=true;


Duplicate code.
return 1;

I don't quite see the need to return a value, but it would be more
sensible to return a boolean, rather than a number.
}
else
{
for(i=0; i<field_to_check.length;i++)
field_to_check.checked=false;
return 0;
}
}

The onClick event to this function is:
<input type='checkbox' name='check_all' value=1 checked
onClick="check(this,
this.form.elements['acct_num_list[]']);">

And the array of checkboxes when there is 1 element in them is:
<input class='copy' type='checkbox' name="acct_num_list[]"
value='something' checked>


A revised and more compact version:

/* In-line this, if you prefer */
function isObject( r ) {
return( r && (( 'object' == typeof r ) ||
( 'function' == typeof r )));
}

function checkAll( group, check ) {
if( isObject( group )) {
if( group.length ) {
for( var i = 0, n = group.length; i < n; ++i ) {
group[ i ].checked = check;
}
} else {
group.checked = check;
}
}
/* Use "return check;" if you want to return the value set */
}

and the call would be modified to

checkAll( this.form.elements[ 'acct_num_list[]' ], this.checked );

Hope that helps,
Mike
 
M

Michael Winter

That's correct. So you need to check whether or not your object
reference is an array first, and treat it differently.

It'll be a collection, actually. Subtle difference.
You can test if it's an array of checkboxes with something like:
function isCheckboxArray(obj) {
return ((typeof
obj.type!="string")&&(obj.length>0)&&(obj[0]!=null)&&(obj[0].type=="checkbox
"));
}

I should think that

if( isObject( ref ) && ref.length ) {

is sufficient (using the isObject() definition from my post). It isn't in
all cases as a single object might have a length property, but it isn't
the case here.

If you were unsure of the type of elements returned in a collection, your
check wouldn't necessarily be reliable. It would be better to check the
type of each element in turn.

[OT]
Also, I have a library which handles "checkbox groups" like this,
including this situation and others you may not have considered. You can
check it out at http://www.mattkruse.com/javascript/checkboxgroup/ if
you wish!

I'm not trying to take sides in the debate that you and Richard are having
(I'm undecided, for the most part), but that script supports his point
against libraries. Whilst it might be a godsend under some circumstances,
it is undeniably overkill for the OP's problem. It would have been better
to point out the mistakes in the OP's code and give a distilled version of
your library function, rather than suggest it as it stands.

[/OT]

Mike
 
M

Matt Kruse

Michael Winter said:
I'm not trying to take sides in the debate that you and Richard are having
(I'm undecided, for the most part), but that script supports his point
against libraries. Whilst it might be a godsend under some circumstances,
it is undeniably overkill for the OP's problem. It would have been better
to point out the mistakes in the OP's code and give a distilled version of
your library function, rather than suggest it as it stands.

That's a valid point, but I do disagree. The library referenced is only 4k,
so even with all the additional features, the size isn't something that will
overload any page.

And it's obvious from the original post that this user is somewhat of a
beginner (the use of eval, etc). I don't think that correcting this specific
example of code will teach the OP a lot about programming JS. However, I
think your response was undoubtedly helpful as well. The OP can decide which
will help him the most.

In the future, the OP might be back, asking how to modify the little snippet
of code he had to support different checkbox names, or pre-checked
checkboxes, etc. If not for this specific page, then possibly for future
pages, where the requirements are slightly different. If the user has my
library (or any other library) in their arsenal, they already have a
superset of problems solved. They can spend their time focusing on business
logic and functionality, rather than re-writing they code every time they
realize that they might want additional features.

For small libraries with very specific functionality - like this example - I
think that pointing someone to a reusable, generalized solution is a good
thing. Learning by examining existing solutions is how many of us learned a
lot of what we know :)
 

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,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top