Gab Royer
Gab Royer

Reputation: 9806

Javascript behaving weirdly

the following function does not work as I thought it should have. For some reason, the loop breaks whenever one the the validate function returns false. Why is that?

Here is my code :

function validateGroup(input) {
    if (!input.value.match(/^[0-9]{0,2}$/)) {
        $(input).addClass("invalidField");
        return false;
    }
    $(input).removeClass("invalidField");
    return true;
}

function validateClass(input) {
    if (!input.value.match(/^[a-zA-Z0-9-]{0,9}$/)) {
        $(input).addClass("invalidField");
        return false;
    }
    $(input).removeClass("invalidField");
    return true;    
}

function validateData() {
    var rows = document.getElementsByTagName("tbody")[0].getElementsByTagName("tr");

    var valid = true;

    for (var i = 0, arrayLength = rows.length; i < arrayLength; ++i) {
        valid = valid && validateClass(rows[i].getElementsByTagName("input")[0]);
        valid = valid && validateGroup(rows[i].getElementsByTagName("input")[1]);
        valid = valid && validateGroup(rows[i].getElementsByTagName("input")[2]);     
    }
    return valid;
}

Thanks a lot!

Upvotes: 1

Views: 185

Answers (5)

erikkallen
erikkallen

Reputation: 34391

It's called short-circuiting. Quick fix: replace each line with

valid = validateClass(rows[i].getElementsByTagName("input")[0]) && valid;

Upvotes: 0

RamboNo5
RamboNo5

Reputation: 2060

I think it's because of the lazy evaluation scheme Javascript uses with &&. Try a single & instead.

Short-circuit evaluation: Support in common programming languages

Upvotes: 0

Ciar&#225;n Walsh
Ciar&#225;n Walsh

Reputation: 1866

It looks like you want to run the validate functions on each iteration even if ‘valid’ was already set to false. However the && operation you are using will short-circuit, so although the loop will continue the validate functions will not be called on subsequent iterations.

A really simple alternative which would work the way you want would be:

for (var i = 0, arrayLength = rows.length; i < arrayLength; ++i) {
   if(!validateClass(rows[i].getElementsByTagName("input")[0]))  valid = false;
   if(!validateGroup(rows[i].getElementsByTagName("input")[1]))  valid = false;
   if(!vvalidateGroup(rows[i].getElementsByTagName("input")[2])) valid = false;
}

Upvotes: 2

Shaun
Shaun

Reputation: 1508

the statement valid && validateClass(...) will not call the validateClass method if valid is false. I think what you want to do is change the order of those to

valid = validateClass(rows[i].getElementsByTagName("input")[0]) && valid;
valid = validateGroup(rows[i].getElementsByTagName("input")[1]) && valid;
valid = validateGroup(rows[i].getElementsByTagName("input")[2]) && valid;

Javascript doesn't bother evaluating the rest of an && expression if it already knows that the result is false.

Upvotes: 12

Pablo
Pablo

Reputation: 1069

It sounds like that is the intent of the function. The three lines of

valid = valid && validate...

mean that if any of the validate functions ever hits false valid will remain false for the rest of the loop.

Upvotes: 0

Related Questions