Jun 18, 2012

JQuery UI Datepicker IE focus fix

The jquery ui datepicker control is quite slick and easy to use, and as you see here it can be customized through various events.

At my current client we have multiple controls on the page that listen for onblur and onchange events to notify of changes to the page (most notably an html5 placeholder enabler). But the datepicker does not send the blur event when a selection happens. Also, our users wanted focus to return the text input field after the date selection. So we need to setup some event handlers to call the blur and focus events upon date selection.

First let’s start with a simple datepicker that is applied to any input field having css class dateInput, with a few extra options:
<pre>
$("input.dateInput").datepicker({
changeMonth: true,
changeYear: true,
showAnim: "fadeIn",
yearRange: 'c-30:c+30',
showButtonPanel: true
});
</pre>

Adding a blur and change event on datepicker selection is rather easy:
<pre>
$("input.dateInput").datepicker({
changeMonth: true,
changeYear: true,
showAnim: "fadeIn",
yearRange: 'c-30:c+30',
showButtonPanel: true,

/* blur needed to correctly handle placeholder text */
onSelect: function(dateText, inst) {
$(this).blur().change();
}
});
</pre>

But adding focus is a little more difficult because of a difference in browser behavior. Simply adding a .focus() to onSelect and onClose will suffice for Chrome and Firefox but IE will reopen the datepicker once it receives the focus. In order to handle IE we can simply implement the beforeShow event handler, returning false when we reach a case where IE should not reopen the datepicker window. I’ve added a fixFocusIE variable to track this:

Hopefully this helps someone else searching for a way to focus on the original input field after selecting a date with the JQuery UI Datepicker control.

About the Author

Jeff Sheets profile.

Jeff Sheets

VP - Technology

Jeff has developed Java, Groovy, Grails, and Javascript web apps for industries as varied as Defense, Energy, Weather, Insurance, and Telecom. He is a co-organizer of the Omaha Java Users Group. Jeff has worked on Grails projects since the Grails 1.3.x days, and has experience with production Groovy code as well as Spock tests and Gradle builds. His latest focus has been on AngularJS and Spring Boot applications using JHipster. Jeff also enjoys volunteering at local CoderDojo events to teach programming to our next generation.

One thought on “JQuery UI Datepicker IE focus fix

  1. Radu says:

    Just when I was losing hope…
    I need this for IE7 and your solution is the only one that I found to be working.
    Thanks Jeff!

  2. Noam Lewis says:

    Thanks!

    I’ve made a revision to your code, to get it to work with jQuery 1.9.1 and jQuery-ui 1.10.1

    https://gist.github.com/sinelaw/5416130

  3. Jeff Sheets says:

    Thanks for the update, and nice solution. I’ll try to modify it to use feature detection in place of $.browser.msie when we upgrade jQuery on this project.

  4. youmo says:

    Thanks, this works for me like a charm.

  5. devaraj says:

    Hi sir,

    i am using datepicker. but when i enter first time manually, automatically adding current date in textbox. How can i fix this?

  6. Jeff Sheets says:

    I’m not sure of your exact issue, but make sure your server-side is not prefilling the date in your input box. Also, perhaps this stackoverflow entry would be helpful:
    http://stackoverflow.com/questions/3668325/jquery-datepicker-no-default-date

  7. chandu says:

    Hi,

    While I’m adding this IE fix facing problem with chrome.

  8. Justin says:

    I have been stuck on this for 2 and a half days, and was so close to giving up. Can’t thank you enough for this.

  9. Ahsan says:

    Hi,
    I have tried this fix, but its still not working on IE 11

  10. Jerome says:

    I definitely have a problem with the code and the beforeShow event. By isolation, I have two fields that call up the calendar. When I add
    ,
    beforeShow: function(input, inst) {
    var result = $.browser.msie ? !this.fixFocusIE : true;
    this.fixFocusIE = false;
    return result;
    }
    the calendar is disabled in Chrome and Safari. Removing it re-enables the calendar. Have no IE on hand to see the result but expect it has the focus problem

  11. samyom says:

    Thanks…nice solution.
    But since $.browser is deprecated, had to use the code here to find the IE version.

    http://stackoverflow.com/a/19999868/294176

    Also I used Noam Lewis’s version from git hub.

  12. Sanjib Ghosh says:

    This code works fine in IE

    jQuery UI Datepicker – Default functionality

    $(function() {
    $( “#datepicker” ).datepicker();
    });

    Date:

  13. Grant says:

    Thanks, This fixes the problem of the calendar re-opening on close, but then once it is closed, it wont re-open if I click the input field. I have to click away (unfocus) then click the input field again to open the calendar again. My users wont know to do this if they want to change the date after selection.

    Also, does anyone know where this problem originated from, because I have 6 other datepickers in the same app and they dont react like this one does.

  14. progmars says:

    Thanks, this works nicely also with Angular, but there seems to be still one problem on IE with this: if you navigate with Tab through fields, then each second focus on datepicker field will not work. Tested on IE12.

  15. progmars says:

    So, I fixed it also for IE not showing datepicker each second time I focus the field. Also, there was a slight logical issue, which still did not affect anything: you set the fixFocusIE field on options, but then later on use it on “this”, but “this” refers to DOM element and not options, so essentially you have two fixFocusIE – one in options (which is unused) and the second one on DOM element itself.

    And also $.browser.msie did not work anymore, I had to invent my own IE detector.

    My code looks like that:

    var el = $(“selector of element I need to assign to datepicker”);
    var options = {}; // actually I fill options from defaults and do some other manipulations, but I left it bare object here for brevity
    options.fixFocusIE = false;

    /**
    * detect IE
    * returns version of IE or false, if browser is not Internet Explorer
    */
    function detectIE() {
    var ua = window.navigator.userAgent;

    if(ua.indexOf(‘MSIE ‘) > 0 ||
    ua.indexOf(‘Trident/’) > 0 ||
    ua.indexOf(‘Edge/’) > 0) {

    return true;
    }

    // other browser
    return false;
    }

    /* blur() and change() needed also to correctly update Angular bindings, if any */
    options.onSelect = function(dateText, inst) {
    options.fixFocusIE = true;
    $(this).blur().change().focus();
    };
    options.onClose = function(dateText, inst) {
    options.fixFocusIE = true;
    this.focus();
    };
    options.beforeShow = function(input, inst) {
    var result = detectIE() ? !options.fixFocusIE : true;
    options.fixFocusIE = false;
    return result;
    };
    /* and this one will prevent from datepicker refusing to show when focusing the field for second time in IE */
    el.blur(function(){
    options.fixFocusIE = false;
    });

    el.datepicker(options);

  16. Vengada Karthik Rangaraju says:

    This solution is great. The following doesn’t work though.

    1. Focus on the input – Opens calendar.
    2. Focus out
    3. Focus back on the input – Does not open.
    4. Focus out
    5. Focus on the input – Opens calendar.

    So the calendar does not open every other time. To fix this I had to make a minor change

    /* blur needed to correctly handle placeholder text */
    onSelect: function (dateText, inst) {
    this.fixFocusIE = true;
    },
    onClose: function (dateText, inst) {
    this.fixFocusIE = true;
    $(this).blur().change().focus();
    this.focus();
    },

    I moved the “$(this).blur().change().focus() inside the onClose function itself, since it will get called anyways after OnSelect. This fixed the problem for me.

  17. Deepak Shakya says:

    IE11 still has this issue. Here is the fix which I have done.

    https://github.com/eternicode/bootstrap-datepicker/issues/236#issuecomment-165447457

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Blog Posts
Android Development for iOS Developers
Android development has greatly improved since the early days. Maybe you tried it out when Android development was done in Eclipse, emulators were slow and buggy, and Java was the required language. Things have changed […]
Add a custom object to your Liquibase diff
Adding a custom object to your liquibase diff is a pretty simple two step process. Create an implementation of DatabaseObject Create an implementation of SnapshotGenerator In my case I wanted to add tracking of Stored […]
Keeping Secrets Out of Terraform State
There are many instances where you will want to create resources via Terraform with secrets that you just don’t want anyone to see. These could be IAM credentials, certificates, RDS DB credentials, etc. One problem […]
Validating Terraform Plans using Open Policy Agent
When developing infrastructure as code using terraform, it can be difficult to test and validate changes without executing the code against a real environment. The feedback loop between writing a line of code and understanding […]