cneeds
cneeds

Reputation: 319

.focus() not working after calling a function

Can anyone please explain why the focus command works properly if the alert( is enabled but doesn't work when I use my errmsgPopper function (as the code is now)?

$(document).on('pageinit', function(){
  // Register a new user
  $(document).on('click', '#Register', function(evnt) {
    if (userName == "" || password == "" || emailAddress == "") {
//      alert("Complete all the input fields");
      errmsgPopper("Complete all the input fields");
      // This next line works correctly if the alert( is used instead of the
      //  errmsgPopper function above
      $('input:text[value=""], input:password[value=""]').first().focus();
      evnt.stopImmediatePropagation();
      return false;
    }
  });

  // Popup error message for 2 seconds
  function errmsgPopper(msg){
    $('#errmsgDiv').html(msg).popup('open', {
      positionTo: $('input:text[value=""], input:password[value=""]').first()
    });
    setTimeout(function(){
      $('#errmsgDiv').popup('close');
    },2000);
  }

  // Save the User name
  $(document).on('blur', '#UserName', function(evnt) {
    var $target = $(evnt.target); 
    userName = $target.val();
  });

  // Save their password
  $(document).on('blur', '#Password', function(evnt) {
    var $target = $(evnt.target); 
    password = $target.val();
  });

  // Save their email address
  $(document).on('blur', '#EmailAddress', function(evnt) {
    var $target = $(evnt.target); 
    emailAddress = $target.val();
  });

});

The HTML:

  <div id="LoginPage" data-role="page">

    <div data-role="header"><h1>Login to ECG</h1>
      <a id="LoginClick" href="#LoginSubmit" title="Submit login details">Submit</a>
      <a id="Register" href="#LoginPage" align="right" title="Register new user">Register</a>
    </div>

    <div data-role="content">
      <form>
        <div>
          <label for="UserName">User name</label>
          <input id="UserName" title="Enter your User Name" tabindex="1" type="text" placeholder="User name" maxlength="10" autofocus>
        </div>
        <div>
          <label for="Password">Password</label>
          <input id="Password" title="Enter your Password" tabindex="2" type="password" placeholder="Password" maxlength="10">
        </div>
        <div>
          <label for="EmailAddress">Email address</label>
          <input id="EmailAddress" title="Enter your email address" tabindex="3" type="text" placeholder="Email address" maxlength="40">
        </div>
      </form>
    </div>

    <div data-role="footer"><h1>Educational card games</h1>
      <a href="#" title="Retrieve your password">Lost PW</a>
    </div>

  </div>

errmsgDiv:

  <div id="errmsgDiv" data-role="popup"><p>msg text</p></div>

I didn't set up a fiddle yet as I suspect there is a simple answer...

Upvotes: 1

Views: 1229

Answers (2)

Omar
Omar

Reputation: 31732

When popup is active, page loses focus as well as any element inside it. Alternatively, you can focus() after popup is hidden/closed.

Modify setTimeout to focus on popupafterclose event.

setTimeout(function () {
  $('#errmsgDiv').popup({
    afterclose: function () {
      $("input[value='']").first().focus();
    }
  }).popup("close");
}, 2000);

Also, you need to manually initialize the external popup.

$(function () {
  $("#errmsgDiv").popup();
});

Update

I have used this little snippet (1) to determine empty fields and then focus() on first one.

var checkEmpty = $('form input').filter(function () {
  return $.trim($(this).val()) == '';
});

This will return an object of all empty fields, pick .first() one to position popup and focus.

Full code

$(document).on('pageinit', function () {
    var checkEmpty; /* global */
    $(document).on('click', '#Register', function (evnt) {
        checkEmpty = $('form input').filter(function () {
            return $.trim($(this).val()) == '';
        });
        if ($("#UserName").val() == "" || $("#Password").val() == "" || $("#EmailAddress").val() == "") {
            errmsgPopper("Complete all the input fields");
            return false;
        }
    });

    function errmsgPopper(msg) {
        $('#errmsgDiv').html(msg).popup('open', {
            positionTo: $(checkEmpty).first()
        });
        setTimeout(function () {
            $('#errmsgDiv').popup({
                afterclose: function () {
                    $(checkEmpty).first().focus();
                }
            }).popup("close");
        }, 2000);
    }
});

Demo

(1) Credit to @thecodeparadox

Upvotes: 1

Matt Burland
Matt Burland

Reputation: 45155

Without more information, this is kind of a guess, but try:

function errmsgPopper(msg, callback){
    $('#errmsgDiv').html(msg).popup('open', {
        positionTo: $('input:text[value=""], input:password[value=""]').first()
    });
    setTimeout(function(){
        $('#errmsgDiv').popup('close');
        if (callback && typeof callback === "function") {
            callback();
        }
    },2000);
}

And then you'd change your call to this:

errmsgPopper("Complete all the input fields", function() { 
    $('input:text[value=""], input:password[value=""]').first().focus();
});

Now your focus will only get changed after the popup has closed.

Upvotes: 1

Related Questions