Forum Moderators: open
I've got a global var which dictates whether my functions display alerts or not.
In opera, it works fine, without problems. In IE6, the global variable seems to be ignored and somehow isn't having it's affect.
I'm making a validation script, after the page is loaded - I loop throught every element of every form (in "checkFields") selecting and then bluring them (.focus(); .blur();) as each validated field has an onblur action (using regex, the validation is done and an error message is displayed if it fails) however, on-load, I dont want this message (I just want the field to by highlight - with a pink background) to appear so I created a global var that must be true for the error to appear...however in IE, the messages appear anyway... Help! :(
here's my code:
<head>
<script type="text/javascript" language="javascript">
var PrevVal=[]
var DispErr = true;
function validateField(field, caps, regex, errmsg) {
if (caps) {
field.value = field.value.toUpperCase();
}
tempprev = PrevVal[field.name];
PrevVal[field.name] = field.value;
if (PrevVal[field.name].match(regex)) {
field.style.backgroundColor = "";
return true;
} else {
//THIS LINE ISN'T WORKING IN IE6!
if ((DispErr == true) && (tempprev!= field.value)) {
alert ( errmsg );
}
field.style.backgroundColor = "pink";
return false;
}
}
function checkFields() {
// SET GLOBAL VAR AS FALSE while I run initial field checks (this function is called at the bottom of my HTML)
DispErr = false;
for (j=0; j<document.forms.length; j++){
for(i=0; i<document.forms[j].elements.length; i++){
if (document.forms[j].elements[i].type == "text") {
document.forms[j].elements[i].focus();
document.forms[j].elements[i].blur();
}
}
}
// REACTIVATE ERROR MESSAGES
DispErr = true;
}
</script>
</head>
<body>
<form>
<input type="text" size="48" onblur="validateField(this, false, '^.+$', 'You must enter an address!');" name="CUS¬address1" value="">
<input type="submit">
</form>
<script> checkFields(); </script>
</body>
I just added
alert (DispErr);
Between this lines, like this
document.forms[j].elements[i].focus();
alert (DispErr);
document.forms[j].elements[i].blur();
Both IE6 and Opera 7.23 output the same value (false), and IE6 now acts as it is suppose to...but I have no idea how to do this without an alert box :(
[edit] I find this strange as the edits I have made (above) are in a separate function to where the error is occuring (I think) and the changes shouldn't even make any difference to the program!
By the way, global variables are very much frowned upon in OO programming. Java doesn't even have them. The closest thing in Java is a static variable, but it is restricted to its class and subclasses.
Another approach might be to create DispErr as an object, which lives on the heap, rather than a primitive that exists on the stack. I'd just use a one value array. That should avoid IE's confusion.
By "Another approach might be to create DispErr as an object, which lives on the heap", do you mean:
function dispAlert(dispErrIn){
this.dispErr=dispErrIn;
}
& creating a new object using
var myobj=new dispAlert(true);
Using like:
myobj.dispErr
If not please elaborate slightly if you can, thanks. :)
Now DispErr resides on the heap as an object, a more permanent and less ambiguous reference than a primitive variable on the stack. Just use standard pass by reference techniques to modify DispErr[0] in the rest of the code.
I'm not sure it will work, but I think it stands a pretty good chance.
<input type="text" size="48" onblur="validateField(this, false, '^.+$', 'You must enter a surname!', DispErr);" name="CUS¬surname" value="">
<input type="text" size="48" onblur="validateField(this, false, '^.+$', 'You must enter a surname!', DispErr[0]);" name="CUS¬surname" value="">
I've tried, at the bottom of my page, this:
<script>
DispErr[0] = false;
checkFields();
DispErr[0] = true;
</script>
and/or this:
<script>
DispErr = false;
checkFields();
DispErr = true;
</script>
But it still refuses to work in IE6!
[edit:]
I just tried
<input type="text" size="48" onblur="validateField(this, false, '^.+$', 'You must enter a surname!', [b]false[/b]);" name="CUS¬surname" value="">
and no message came up, so it obviously is not passing the correct variable into the functions when they are called.
My guess is that one function isn't getting to finish before the other begins. If one is called by a script in the body and the other by onload(), the load event completes when the body script is loaded, NOT when it finishes execution.
It appears that whenever checkFields() completes, it's going to return true. Only if it hasn't completed should false still be the value of DispErr.
You could put a timeout in cF before returning DE to true, if all you want is let vF do its test before cF is finished. I'm not sure what you're accomplishing by this, though.
Hold the phone, I think I get it now, you just need to exit cF after the focus, before reassigning the variable to true by putting a return statement after the focus. Reassign the true value to DE at the end of vF. How does that sound?
However, you still have to deal with the fact cF isn't completing in Opera. I think you may be better off calling vF from cF, rather than using the onblur event to trigger it.
In part, you have this problem because you are trying to validate on the fly instead of onsubmit, the usual time for validation. That would work okay, if you weren't also trying to prevalidate with the same code. Why do you have to validate before there is any input, anyway?
I think the timeout should work anywhere before the reassignment of the variable to true, but any way you do it, it's really a kludge. In actual use, the return of true will only happen after the last iteration of the loops, yet you will be timing-out each iteration.
[edited by: Rambo_Tribble at 8:54 pm (utc) on Mar. 17, 2004]
At the moment I can't replicate the alert behaviour of allowing other functions to continue whilst it stops the loop.
[edit] Regarding your last post - I need to highlight the fields that need validation when the page loads. I, however, guess I could do this using a CSS style attribute. I just wanted everything to do with a field's validation in one place (onblur attribute) and everything else use that.
I'm just going to disable the alert message :)
EDIT: thanks for your help :)
I don't think you'll find that to be the case when the functions are initiated by separate events, as in this case. I think the only way to get the sequential processing you are looking for is to call vF from cF. Then vF will finish before cF executes the next instruction. Perhaps you could parse the value of your onblur attribute within cF to get the parameters to pass.
[edit:] When I say finish, I mean that, for example, .blur() is run and my "onblur" function is also finished. I agree that the 'blurring' is finished before my onblur function is started which is what is causing the problem, but I think they should be logically linked by IE, as they are in Opera (I assume...again ;))
Anyway, I now understand more about JS/HTML relationship, solved this particular problem as I think that the alert message is not necassary.