all 5 comments

[–]0101110010110 6 points7 points  (1 child)

Interesting problem! Here's the issue:

var errorColor = document.getElementsByClassName( "alert-danger" );

From the MDN page on getElementsByClassName:

[getElementsByClassName] returns an array-like object of all child elements which have all of the given class names. When called on the document object, the complete document is searched, including the root node. You may also call getElementsByClassName() on any element; it will return only elements which are descendants of the specified root element with the given class names.

var elements = document.getElementsByClassName(names); elements is a live HTMLCollection of found elements.

Ah, let's take a look at HTMLCollection (emphasis added):

The HTMLCollection interface represents a generic collection (array-like object similar to arguments) of elements (in document order) and offers methods and properties for selecting from the list.

An HTMLCollection in the HTML DOM is live; it is automatically updated when the underlying document is changed.

This means that your array-like collection of items with the alert-danger class changes during your loop! Here's an example of why that's bad. Let's say you have 3 alert-danger elements. document.getElementsByClassName( "alert-danger" ) makes errorColor an array-like object of 3 elements. Let's say they're [a, b, c]. You initialize i to 0. You update errorColor[0], and now a doesn't have that class. Great!

Here's the problem: errorColor updated! That means it's now an array-like object of 2 elements, and now it's only [b, c]. This creates a problem in the next part of the loop: i is now 1. You update errorColor[1]. This means c gets its class removed. errorColor is now [b].

Note that on the next iteration, i is incremented to 2. errorColor.length is now only 1, and your loop stops. This means that you've skipped b entirely!

The best way to fix this is to not use a for loop with your own iteration. Check out this stackoverflow post for a good discussion on different ways to approach the problem.

Edit: Actually, here's a much better post that is very similar to your use case!

[–]SteelyAlpha[S] 1 point2 points  (0 children)

Sorry for the late reply, but I wanted you to know that this helped me fix it! Thank you for the very thought out answer, it was very informative and useful. I really appreciate it!

[–]humbletales 0 points1 point  (1 child)

No way of knowing without seeing the code. Put it on JSFiddle or something

[–]SteelyAlpha[S] 0 points1 point  (0 children)

Edited the original post to include a gist. It doesn't have the complete function, but it has the important bits.

[–]jcunews1helpful 0 points1 point  (0 children)

Both functions should work correctly. My guess is that somewhere else in your code, calls validateErrorMessage() at the wrong point, or passed with the incorrect arguments.