Reputation: 43156
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
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
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
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