Something very strange happens here (only under IE): " alert("Are there any errors? -> " + errors); //--> gives false alert("And now? -> " + errors); //--> gives true " here is the complete code: <html> <head> <title>I hate IE</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> </head> <body> <SCRIPT LANGUAGE="JavaScript"> <!-- var errors = false; function required(HTMLInputElement, message) { removeError(HTMLInputElement,message); if(!HTMLInputElement.value) createError(HTMLInputElement,message); } function createError(HTMLInputElement, errorMessage){ if(!errors) errors = true; var errorMessage = document.createTextNode(errorMessage); var divObj = document.createElement("DIV"); divObj.className = "formErrorLine"; divObj.appendChild(errorMessage); try{ divObj.attributes["id"] = "errorMessage"; }catch(e){} try{ divObj.attributes["id"].value = "errorMessage"; }catch(e){} HTMLInputElement.parentNode.parentNode.parentNode.insertBefore(divObj, HTMLInputElement.parentNode.parentNode.nextSibling); } function removeError(HTMLInputElement, errorMessage){ if(HTMLInputElement.parentNode.parentNode.nextSibling.nodeType == '1' && HTMLInputElement.parentNode.parentNode.nextSibling.firstChild.data == errorMessage){ HTMLInputElement.parentNode.parentNode.nextSibling.parentNode.removeChild(HTMLInputElement.parentNod e.parentNode.nextSibling); } } function validateForm(){ errors = false; validateHTMLInputElements(); /* normally, this would be the last line of this function: return (!errors); */ //these alerts are here to show the problem: alert("Are there any errors? -> " + errors); alert("And now? -> " + errors); return false; } function validateHTMLInputElements(){ var HTMLInputElements = document.getElementsByTagName("input"); for(i=0; i < HTMLInputElements.length; i++){ try { var type = HTMLInputElements.attributes["type"].value; HTMLInputElements.focus(); }catch(e){} } } // --> </SCRIPT> <form name="register" method="post" onSubmit="return validateForm()" > <div class='formLine'> <div class='formLabelHeader'><label for="f_name">First name: </label></div> <div class='formElementHeader'><input type="text" name="f_name" onblur="required(this,'please fill in your first name!'); "></div> </div> <div class='formLine'> <div class='formElementHeader'><input type="submit" class="button" value="REGISTER" ></div> </div> </form> </body> </html> To get the 'error', just open the page and push register. Please help me find a solution without having to use the alert() function.
try{ divObj.attributes["id"] = "errorMessage"; }catch(e){} try{ divObj.attributes["id"].value = "errorMessage"; }catch(e){} Code (markup): the first try works with some browsers like Opera & Mozilla, the second try works with I.E. I use it because I'm to lazy to use: if(browser == Mozilla OR browser == Opera OR ....){ divObj.attributes["id"] = "errorMessage"; } else{ if (browser == I.E. OR ...){ divObj.attributes["id"].value = "errorMessage"; } else { if(couldn't detect which browser you are using){ try{ divObj.attributes["id"] = "errorMessage"; }catch(e){} try{ divObj.attributes["id"].value = "errorMessage"; }catch(e){} } } } Code (markup):
The error is being created on the blur event from the required() function (actually from its call to createError). Apparently the first alert is being executed before the event either fires or is handled by the required() function. But when you hit the submit button, the text field is blurred, so it triggers that event and hence the required() function.
I'm don't know if you just gave me an answer or just asked me a question. But from what I understand, you are completely correct. On the f_name input element is the onBlur trigger (which triggers required() on that element, which creates a DIV with errorText and puts errors on true if needed). On the form itself is the onSubmit trigger (which triggers validateForm(), which puts variable errors on false, then just activates the onblur function on each input element by doing focus() and ending with the button, where it focusses last, and then it should return the opposite value of variable errors. This return value determines wheter the form is submitted or not) Originaly, instead of working with the variabele errors, the validateForm() triggered all onblurs and then looked whether there was an element with ID = errorMessage. This didn't work in IE as well, because of the same reason as it isn't working now. Meaning that if I would have done: alert(""); before doing document.getElementByID("errorMessage"); it would have worked as well in internet explorer. (I didn't knew that this would 'solve' the problem at that time though) After that I tried it with looking for all DIV's with classname = formErrorLine which also worked perfect on all browsers except for I.E., and then I noticed that when I took all DIV elements into a NodeList, IE didn't include the recently generated errormessage-DIV's. (Doing an empty alert again before retrieving these elements would have been a workaround there again, giving me an unwanted alert, but a working code) Now I just made it clearer to understand the problem, but heck, it still blows my mind that I have to do an unwanted alert in order to make it work. The best workaround I've found so far was this: if(browser == IE) alert('please download firefox'); but since I'm trying to make some professional site, I can't afford this message. *while writing all of this, I suddenly realise your point:* Obviously, you are right that, in IE, the events attached to an input are activited to late. And since the only way in Javascript to let the code sleep for real is by sending some alert or other kind of message box... I will not be able to use .focus() for IE. Which means I'm now looking for a way to activate the onblur function directly, and since I'm not at work now, It will be for tomorow. Anyways, I was really stuck on this since I'm used to program in OO languages, where this behavior is not normal. So thank you very, VERY much! You are a true javascript expert
Thanks alot LogicFlux , I solved it by using: function validateForm(){ errors = false; validateHTMLInputElements(); return (!errors); } function validateHTMLInputElements(){ var HTMLInputElements = document.getElementsByTagName("input"); for(i=0; i < HTMLInputElements.length; i++){ try { if(HTMLInputElements[i].attributes["onblur"].value && !(HTMLInputElements[i].attributes["onblur"].value == 'null')){ var start = HTMLInputElements[i].attributes["onblur"].value.indexOf('('); var end = HTMLInputElements[i].attributes["onblur"].value.indexOf(','); var code = HTMLInputElements[i].attributes["onblur"].value.substring(0,start + 1)+"HTMLInputElements[i]"+HTMLInputElements[i].attributes["onblur"].value.substring(end); eval(code); } }catch(e){} } } Code (markup): It works like a charm, and I don't need to rewrite the code again to validate the form as a whole. Looks a little bit complex, but I just steal the code from the onblur attribute, and reuse it directly... (instead of activating the onblur event). So, once again, thanks alot, It took about 100 people to view it (also on other forums) before I got this decent reply from you.
Is horrible!!! Why not: if(divObj.attributes["id"].value) divObj.attributes["id"].value = "errorMessage" else divObj.attributes["id"] = "errorMessage" ?
I knew it was a dirty trick to use try() catch there, but heck, didn't feel like looking any further to make it work on a 'clean' way. Thanks for the good hint there MMJ, it's realy nice to put that try catch away and replace it with this one line (even though I no longer need to set this attribute since I no longer detect errors using getElementById() ): divObj.setAttribute("id", "errorMessage");