Hi,

> Shouldn't returning true exit directly from the function?

It does -- it returns from the function it's in. The function it's in
is the anonymous one that #each has called for that particular
checkbox, not the testRecipient function.

Four ways you can rewrite that to work. The first three keep using
#each, the fourth just opts for a simple loop. Here are two of the
#each options:

// #each, version 1. Keeps track of return flag, but doesn't short-
circuit the loop.
function testRecipient() {
    var required = ["dir", "dev", "pub", "web"];
    var okay = false;

    required.each( function (name) {
        if ( !okay && $(name).checked ) {
            okay = true;
        }
    });

    if ( !okay ) {
        alert('Please select at least one recpipient for your
email.');
    }
    return okay;
}

// #each, version 2. Keeps track of return flag and terminates the
loop early.
function testRecipient() {
    var required = ["dir", "dev", "pub", "web"];
    var okay = false;

    required.each( function (name) {
        if ( $(name).checked ) {
            okay = true;
            throw $break;   // <== The new bit, see notes
        }
    });

    if ( !okay ) {
        alert('Please select at least one recpipient for your
email.');
    }
    return okay;
}

(Side note: Unless you prefer it for clarity, which is fine, there's
no _technical_ reason for writing "if ( $(name).checked == true )",
simply "if ( $(name).checked )" is all you need. The statements are
functionally identical from the JS interpreter's standpoint.)

A note about that "throw $break" thing on v2: The $break object is a
special object defined by Prototype for exactly this situation,
wanting to break an #each loop early. #each catches exceptions and, if
the exception === $break, just returns early (otherwise it re-throws
the exception). But $break no longer appears in the documentation and
I think one of the core team said it was going to be dropped at some
stage.

Actually, there's a third #each option as well:

// #each, version 3. Uses an exception to report success
function testRecipient() {
    var required = ["dir", "dev", "pub", "web"];
    var okay = {};

    try {
        required.each( function (name) {
            if ( $(name).checked ) {
                throw okay;
            }
        });
    }
    catch (e) {
        if (e === okay) {
            return true;
        }
    }

    alert('Please select at least one recpipient for your email.');
    return false;
}

My problem with v2 and v3 is that they throw an exception in the
*normal* case (the user has ticked one of the required boxes). That's
not what exceptions are for, they're for _exceptional_ conditions. I
don't like v1 because it doesn't short-circuit, but it's not like it's
a long loop so that doesn't matter.

I'd probably go with a simple loop:

// A simple loop
function testRecipient() {
    var required = ["dir", "dev", "pub", "web"];
    var index;

    for (index = 0; index < required.length; ++index) {
        if ( $(required[index]).checked ) {
            return true;
        }
    }

    alert('Please select at least one recpipient for your email.');
    return false;
}

...but I come from a procedural and class-based OOP background, not a
functional background. (Does that make me dysfunctional?)

Side note 2: I just noticed a typo in your error message when reading
this message back, one I faithfully reproduced in all of the above,
having read right past it. :-) "recpipient" has an extra "p" in it
(should be "recipient").

HTH,
--
T.J. Crowder
Independent Software Consultant
tj / crowder software / com
www.crowdersoftware.com


On Apr 13, 7:53 pm, sporkit <[email protected]> wrote:
> I'm trying to validate that at least one checkbox of 4 has been
> selected.  The code seems simple enough to me.
>
> function testRecipient() {
>         var required = ["dir", "dev", "pub", "web"];
>         required.each( function (name) {
>                 if ( $(name).checked == true )
>                         return true;
>         });
>
>         alert('Please select at least one recpipient for your email.');
>         return false;
>
> }
>
> Shouldn't returning true exit directly from the function?  Even if I
> reach the return true statement, the function keeps looping until it
> reaches the alert and returns false.  I could probably throw $break,
> but I feel as if I'm missing something really important here...
>
> Thanks!!!

-- 
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en.

Reply via email to