views:

155

answers:

3

I have an ASPX web form. I use jQuery to simply my Javascript. I use a Javascript validation script to validate each of the form fields' values. If an error occurs, I popup an alert with an error message. Then I transfer focus to the underlying element.

Here are examples I have tried.

Using jQuery:

var Form_FieldDef = function(name) {
    this.name = name;
    this.SetFocus = function() {
        $('#' + this.name)[0].focus();
    }
    this.Validate = function() {
        var isvalid = true;
        if ( $.trim($('#' + this.name).val()) == '') {
            alert("Your entry is empty");
            this.SetFocus();
            isvalid = false;
        }
        return isvalid;
    }
}

This works on IE7, IE8, Opera, Chrome, and Firefox. It does not work on Safari 4 on PC. I don't have a Mac.

So I changed the SetFocus method to this.

this.SetFocus = function() {
    var fld = document.getElementById(this.name);
    if (fld != null)
        fld.focus();
}

This works on IE7, IE8, Opera, Chrome, and Firefox. It does not work on Safari 4 on PC.

I stepped through the code with VS 2008 debugger, and I'm calling the focus method on the underlying element.

A: 

This is a hunch: try changing the focus in a timeout routine:

this.setFocus = function() {
  var self = this;
  setTimeout(function() {
    $(self).focus();
  }, 1);
};
Pointy
I tried it. It didn't solve the problem either. I even changed the timeout from 1 ms to 100 ms. And I changed the logic to this.setTimeout("document.getElementById('" + this.name + "').focus();", 100);That doesn't work in Safari either, but it does work in the other browsers. This looks like a bug in Safari event bubbling.
Rob
Well I can get Safari to focus() for me. This is a weird problem.
Pointy
A: 

My own hunch: It's possible that your use of 'this' inside anonymous functions is referencing whatever anonymous function it appears inside, making the use of 'this' ambiguous. Maybe this slight modification will behave differently (untested):

var Form_FieldDef = function(name) {
    var parentRef = this;
    this.name = name;
    this.Validate = function() {
        var isvalid = true;
        var elem = $('#' + parentRef.name);
        if ($.trim(elem.val()) == '') {
            alert("Your entry is empty");
            elem.focus();
            isvalid = false;
        }
        return isvalid;
    }
}
segfault
For Safari, what if you just reverse the order of the focus() and the alert()? Functionally, shouldn't it not matter what order they're in (the input should be focused but not "interactable" until the alert is dismissed?) Or would dismissing the alert cause the input to lose the previously-attained focus?
segfault
A: 

Thanks for your response. I tried your suggestion and it didn't work. Seems strange that the "this" variable would be ambiguous only in Safari. I've added some style to the class so that the input fields get red boxes around them to indicate which field has the error. But the alert box definitely interferes with the placement of the focus.

I can focus, because I place the cursor in the first field when I load the page. It's the alert box that seems to interfere with the placement of the focus, but only in Safari.

Rob