views:

99

answers:

3

I have such code:

function allValid() {
    $('input').each(function(index) {
        if(something) {
            return false; 
        }    
    });

    return true;

}

which always returns true as return false; affects anonymous inner function. Is there an easy way to call outer function's return?

PS. I am not looking for a workaround, just want to know the answer to original question. If the answer is "not possible" it is fine.

+4  A: 

Yeah, store it in a local variable.

function allValid() {
  var allGood = true;
  $('input').each(function (index) {
    if (something) {
      allGood = false;
    }
  });

  return allGood;
}
bcherry
Which is not efficient as if first element is incorrect the rest 1000 will be checked anyway.
serg
@serg555: then do `return (allGood = false)` inside `.each`. That will break out of the loop early.
Roatin Marth
@Roatin Marth - It's a closure run per element, it doesn't behave like simple loop, think of it as a function inside a function.
Nick Craver
@Nick Craver: `return false` inside `.each` breaks the loop. It's a special case jQuery looks for. http://github.com/jquery/jquery/blob/master/src/core.js#L537
Roatin Marth
Yeah if performance is going to be an issue (it usually is not), then `return false`. The example did not make clear how many elements would be matched by `$('input')`.
bcherry
+2  A: 

You can also do this with filter:

var anyInvalid = $('input').filter(function(index) {
                   if(inValidCheck)
                     return true;
                 }).length;

This works because 0 is treated as false, but it actually gives you the number of invalid, which you could use this to display "You have 3 invalid entries" or something if you wanted.

Nick Craver
A: 

If you want to do this efficiently, I think this is the best way:

function allValid() {
  elements = $('input')
  for (i = 0; i < elements.length; i++) { invalidityCheck(elements[i]) && return false; }
  return true;
}

Edit: Although a more JavaScript-y version would probably use exceptions:

function allValid() {
  try
    $('input').each(function(index)) {
      if (something) { throw 'something happened!'; }
    });
  catch (e) {
    if (e == 'something happened!') {
      return false;
    } else {
      throw e;
    }
  }
  return true;
}
intuited
@Roatin Marth: Thanks for the tip on returning from .each(). It's actually documented, I just missed that. "http://api.jquery.com/each/"
intuited
I don't see how using exceptions is more JavaScript-y. You should never be using exceptions for logic flows, in any programming language.
bcherry