T J
T J

Reputation: 43156

Empty validation not working in a particulor empty textbox

I've few similar textboxes. When i run the validation script given below, One of them isn't affected the first time, even though it's empty. I'd like to know why.

Following is the HTML:

<input type='text' class='txt' value="" />
<input type='text' class='txt' value="" />
<input type='text' class='txt' value="" />
<input type='button' onclick='validate()' value='validate' />

JS:

function validate() {
 var txts = document.getElementsByClassName('txt');
 for (var i = 0; i < txts.length; i++) {
    if(txts[i].value === "")
       txts[i].className = 'txtError';
 }
}

and CSS:

.txt {
  border:1 px solid green;
}
.txtError {
  border:1 px solid blue;
  background:red;
}

This might be a dumb mistakes but i stared at it many times and my eyes isn't catching anything at the moment. I also tried it in different browsers.

Here's a JSfiddle demonstrating the problem.

Side note: i'm not looking for another validation script, i just want to know why the second textbox escapes the validation.

Upvotes: 0

Views: 75

Answers (3)

George Mauer
George Mauer

Reputation: 122062

Because getElementsByClassName returns a live collection. Meaning it is updated underneath you as you change the DOM. So when you remove the txt class from the first box (replacing it with txtError you suddenly have an enumerable of size 2 instead of 3.

To fix it you can convert the live collection to a regular array using the array slicing trick

    var txts = Array.prototype.slice.call(document.getElementsByClassName('txt'), 0);

However there are better ways to achieve pretty much everything that you're doing here. SO isn't really the place to discuss this but once you get it working go ahead and post it on the codereview stackexchange for feedback.

Upvotes: 4

RevanProdigalKnight
RevanProdigalKnight

Reputation: 1326

I think the problem arose because you were changing the class entirely instead of just adding a class; at least, it fixed the problem for me.

Here's a jsfiddle I created from yours that works fine by changing the behaviour to something more like jQuery's .addClass() method - I set .className = 'txt txtError' instead of just changing it to txtError.

Upvotes: 0

John Hartsock
John Hartsock

Reputation: 86872

This seems like a strange issue and I cannot fully explain the issue. But when debugging and stepping though the code, every time you update the classname of one of the elements, your collection of txts decrements. Therefore, this is the only way I can think of to fix it. Basically the same thing you have, but instead I start with the last element of the txts array, instead of the first.

function validate() {
    var txts = document.getElementsByClassName('txt');
    for (var i = txts.length - 1; i >= 0; i--) {
        if (txts[i].value === "") txts[i].className = 'txtError';
    }
}

Upvotes: 0

Related Questions