Forum Moderators: open

Message Too Old, No Replies

strange behaviour difference between Opera and IE6

         

megablimp

12:29 pm on Mar 17, 2004 (gmt 0)

10+ Year Member



Hi,

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>

Rambo Tribble

2:17 pm on Mar 17, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Have you checked to see the actual value of DispErr at the point of IE's failure?

megablimp

2:33 pm on Mar 17, 2004 (gmt 0)

10+ Year Member



Yes, before the line

if ((DispErr == true) && (tempprev!= field.value)) {

I put:


alert (DispErr);

In Opera, it outputs false.
In IE6, it outputs true.

[edit] btw I'm running Opera 7.23

Rambo Tribble

3:14 pm on Mar 17, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Can you modify your script to explicitly pass the value of DispErr to the validateField() function? It sort of sounds like IE is using it as a local variable in checkFields(), despite your having declared it in the start of your script.

megablimp

3:22 pm on Mar 17, 2004 (gmt 0)

10+ Year Member



If that's the only solution, then yes.

Just thought it was odd as this is a common usage of global vars is it not?

megablimp

3:26 pm on Mar 17, 2004 (gmt 0)

10+ Year Member



Hmmm

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!

Rambo Tribble

3:54 pm on Mar 17, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Aha! I think by taking elements in and out of focus you are confusing IE as to what document DispErr belongs to, since focus is commonly used between windows. You can probably remedy the problem by making sure the overarching document that hosts the function is in focus when you set the variable's value.

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.

megablimp

4:47 pm on Mar 17, 2004 (gmt 0)

10+ Year Member



Thanks Rambo Tribble,

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. :)

Rambo Tribble

4:58 pm on Mar 17, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Just instead of the simple variable declaration of DispErr you're now using, something like:
var DispErr=new Array(1);
DispErr[0]=true;

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.

megablimp

5:17 pm on Mar 17, 2004 (gmt 0)

10+ Year Member



I just tried numerious ways,
I tried inputted the variable in the "onblur" action like so:

<input type="text" size="48" onblur="validateField(this, false, '^.+$', 'You must enter a surname!', DispErr);" name="CUS¬surname" value="">

and using your suggested method (with the correct declaration):

<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.

Rambo Tribble

5:34 pm on Mar 17, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Okay, let's back up and find out for sure where IE is getting the true from. Make the original variable assignment false, then run the script and see what IE does. Then return that assignment to true and change the assignment at //REACTIVATE to false and see what it does.

megablimp

5:53 pm on Mar 17, 2004 (gmt 0)

10+ Year Member



Ok, IE gets it's "true" value from the "// REACTIVATE" line, once that is set to false, IE no longer shows the alerts :).

Does this mean that IE gets the values AFTER my loop?

Somewhat confusing :)

Rambo Tribble

6:14 pm on Mar 17, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The key to unraveling this has to be the fact that alert() changed the behavior. The effect of alert() is basically the same as a timeout, it delays the current execution and gives another process time to catch up.

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.

megablimp

6:24 pm on Mar 17, 2004 (gmt 0)

10+ Year Member



ok well I've been working on a work around, nothing yet but some 'interesting' behaviours coming to light :¦

Rambo Tribble

6:29 pm on Mar 17, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You know, it would make sense that validateField would fire as soon as the focus is taken off the input field by the activation of checkFields. If checkFields completes before vF gets to its test, DispErr is true, if it doesn't the value is false. The different interpreters are just completing the loops at different rates. You may have to rethink what you assign to DispErr and when.

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.

megablimp

7:38 pm on Mar 17, 2004 (gmt 0)

10+ Year Member



Hm I think I see what your saying, but how will the loop continue after I return a value from cF. Calling vF from cF will be difficult due to the parameters, maybe I should timeout before moving on to the next loop between focus and blur?

Rambo Tribble

8:34 pm on Mar 17, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Okay, I was thinking with just the one field, but you want to loop through several in the actual application.

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]

megablimp

8:51 pm on Mar 17, 2004 (gmt 0)

10+ Year Member



Basically I want each field to be highlighted if it's not acceptable, I actually have a system where onsubmit, it loops throught the form elements, to check to see if their backgroundColor is pink (highlighted, therefore invalid).

At the moment I can't replicate the alert behaviour of allowing other functions to continue whilst it stops the loop.

Rambo Tribble

8:58 pm on Mar 17, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I added to the previous post, so you might want to review it. While I get the check-on-the-fly thing, I still don't see why you have to validate when the page is loaded, before any user input.

megablimp

8:59 pm on Mar 17, 2004 (gmt 0)

10+ Year Member



I think I'm just going to scrap the error message...much simplier ;]

[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.

Rambo Tribble

9:06 pm on Mar 17, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Why not just scrap checkFields? It's the real source of your headaches. As near as I can tell, all it's doing is running through the fields when the page is built making sure the fields have valid strings, but you should be in command of what is in the fields when the page builds, so what's the point?

megablimp

9:08 pm on Mar 17, 2004 (gmt 0)

10+ Year Member



True but I really just wanted to separate my validation from my PHP, which is complicated enought. Validation being handled 100% by javascript, which is why I wanted to avoid the css style field background as I mentioned above (as the data put in the form would need to be validated by PHP, server-side). I still dont see why I can't do this, surely this is a bug of some kind?
In any other language it runs functions as it meets them being called and finishes them before the next function is run....right?

I'm just going to disable the alert message :)

EDIT: thanks for your help :)

Rambo Tribble

9:32 pm on Mar 17, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



"In any other language it runs functions as it meets them being called and finishes them before the next function is run....right?"

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.

megablimp

9:48 pm on Mar 17, 2004 (gmt 0)

10+ Year Member



I see, I assumed that .focus() and .blur() are just like custom functions, as in, they behave in the same way (ie allowed to finish before the script moves on).

[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 ;))

Rambo Tribble

10:01 pm on Mar 17, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I think that when blur() is run it triggers the HTML event, onblur, therefore the code initiated by onblur is completely independent of the code in the function calling blur(). If you call vF from cF you can avoid having to use the blur() function to initiate the onblur event. Am I being clear? onblur isn't a function, it isn't even JavaScript, it is HTML that calls JavaScript.

megablimp

10:07 pm on Mar 17, 2004 (gmt 0)

10+ Year Member



oh yes sorry, I should have realised. The HTML event is being triggered by my javascript, which is then running the other javascript - completely unrelated. Ok I get you now :)

Anyway, I now understand more about JS/HTML relationship, solved this particular problem as I think that the alert message is not necassary.

Rambo Tribble

10:24 pm on Mar 17, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Anyway, to finish up, what I was suggesting is that if you have to call vF from cF, you can read the value of the onblur attribute value string (since it is just an HTML attribute) with standard dot notation and pass the value, then, from cF to vF without much trouble.