HELP: blur infinite loop!?!?

So I thought I was begin clever. I wanted to validate fields on a form as the user is “finished” with them. I didn’t want to use keystroke watching ( for enter/return/tab) , as that seems resource heavy and also the user could simply use the mouse to navigate about. So instead I attached a function to all my Input fields so I could perform quick validations; essentially el.onblur=function(){…}

Whats happening , however is that , when she user moves on to another element the original element loses focus and the function is called and (if the field is wrong) an error message is displayed ( that what I was expecting)… what I wasn’t expecting is that the new element gains focus then LOSES FOCUS when the error message is displayed for the previous element … which then triggers THAT element’s validation function which spirals into an infinite loop.

I guess I was wondering if there was a way around this… be it by preventing the next element from gaining focus until he previous has been validated… or well am at a loss really. Any advice would be greatly appreciated

Throw a global flag (yeah, I know - that’s sacrilegious) when the error is thrown, and check that on the onblur before throwing the error?

Use onchange.

Use on change on a text input?

Dave, am uncertain of what you mean.
I have used an alert (el.id); as part of my debugging routine.

The first alert that pops is the field I was typing ( this is as expected… it was meant to signal that that field had lost focus and was being validated) , but immediately after i lose that alert window. another pops up telling me the NEXT field is being validate ( which is is of course an invalid value since I didn’t even get to type anything). closing that window… i get an immediate warning about the same field… at infinitum until I force quit the browser.

My best guess is that upon blur, the next field gains focus, which of course is then lost when closing the alert window , and causes that other element to lose focus … throwing an alert window… and the process repeats.

so maybe if there was a way to time out the UA focus until my validation has completed?

Hi,

It does emit a change event, so it would be conceivable to use it.
http://www.quirksmode.org/dom/events/change.html

This seems conceivable.
Why don’t you just use a way of alerting the user to a failed validation which doesn’t steal the focus?

E.g.

<p>
  <label for="userName">User Name:</label>
  <input type="text" id="userName">
  <span class="errorMessage"></span>
</p>
<p>
  <label for="passWord">Password:</label>
  <input type="text" id="passWord">
  <span class="errorMessage"></span> 
</p>

JS:

var inputs = document.querySelectorAll("input"), 
    len = inputs.length, 
    i;

function makeBlurHandler() {
    "use strict";
    return function () {
      if (this.value === "") {
        this.nextElementSibling.innerHTML = "Cannot be blank!";
      } else {
        this.nextElementSibling.innerHTML = "";
      }
    };
}

for (i = 0; i < len; i++) {
    inputs[i].addEventListener("blur", makeBlurHandler());
}

Demo

Is this the kind of thing you are looking for?

Yes Pullo… that works
but am confused… why would adding an event handler be any different than
el.onblur=function (){…}?

It comes in most useful in terms of “DRY”. If you have a page full of elements where you want them all to do the same thing it’s a lot “cleaner” and easier to maintain if things need tweaking.

1 Like

That’s just DOM Level one vs DOM level two (see here)
Your syntax should work, too:

for (i = 0; i < len; i++) {
    inputs[i].onblur = makeBlurHandler();
}

Demo.

Or even:

for (i = 0; i < len; i++) {
    inputs[i].onblur = function() {
      if (this.value === "") {
        this.nextElementSibling.innerHTML = "Cannot be blank!";
      } else {
        this.nextElementSibling.innerHTML = "";
      }
    }
}

Demo.

Thanks Pullo.

For the record , I solder the issue with a global flag. It’s false by default, true when validating, and back to false when finished. My val function skips the onblur=validate() when the flag is true. Thanks for you help!