4

I use the jQuery UI Datepicker plugin and I found that if the plugin is open and the user clicks a label element setting focus to the field which the datepicker is bound to, the blur event fires, thus the datepicker fades out. This is immidiately followed by the focus event, fading the datepicker back in. However, when the blur event fires again, the datepicker dialog remains open when the input field loses focus.

My markup is quite basic:

<label>Select date <input type="text" id="datepicker" /></label>
<script type="text/javascript">$('#datepicker').datepicker(options);</script>

I reproduced the error on the jQuery UI Datepicker page by typing the following in the console:

$('h2:first').html('<label for="datepicker">Datepicker</label>');

When the datepicker is open, try clicking on the heading.

I guess I can remove the label for datepickers, and disabling the animation might help, but I want to maintain the user experience these features provide. Can anyone help me with some inspiration on how to solve this?

Jørgen
  • 8,820
  • 9
  • 47
  • 67

3 Answers3

5

I was having the exact same problem as you (in fact your question came up during my googling).

I believe the problem is in the version of jQueryUI you are using vs what was shown in @ShadowScripter's jsFiddle. I encountered this problem using v1.8.17 and v1.8.18, but the jsFiddle uses v1.8.16 (which doesn't reproduce the bug). Here's a jsFiddle which does reproduce the bug using v1.8.18.

So I diffed v.18 against v.16, did some code swapping and found the culprit:

In Datepicker.prototype._hideDatepicker, postProcess() is defined as:

v1.8.18:

var self = this;
var postProcess = function() {
    $.datepicker._tidyDialog(inst);
    self._curInst = null;
};

v1.8.16

var postProcess = function() {
    $.datepicker._tidyDialog(inst);
    this._curInst = null;
};

So when the label is clicked while datepicker is open, this in v.16's postProcess() is an HTMLDivElement object while in v.18, self is a Datepicker object. _curInst is an attribute of Datepicker so the code in v.16 is assigning _curInst to the wrong object (the HTMLDivElement instead of Datepicker). This mistake gets fixed in v.18 but it introduces this "stuck open" bug.

Simply removing self._curInst = null; from v.18 fixes the "stuck open" bug. I'm not sure what, if any, side effects this may cause, but I didn't notice any issues during my initial testing although your results may vary.

dgilland
  • 2,758
  • 1
  • 23
  • 17
2

This is fixed in Jquery UI v1.8.19

0

Hm, I can't seem to reproduce your problem.
When I try it in this JSFiddle, the focus still remains on the input.
In any case, the correct html markup for a label is not to envelop the entire input within the label.
That is what the for attribute is for.

Do this instead

<label for="datepicker">Select date</label><input type="text" id="datepicker" />

Here's some information about the label attribute for

Odds are, there might be some of your own code interfering. For example, if you're using a return statement somewhere that stops propagation on that particular element. You can read more about that here.

Community
  • 1
  • 1
ShadowScripter
  • 7,314
  • 4
  • 36
  • 54
  • Thanks :) I can see it works in your jsfiddle! However, wrapping inputs in label is valid, and nessessary if you want to avoid IDs on every element. Note that I reproduced the error by adding a label with for attribute to the DOM using console on http://jqueryui.com/demos/datepicker/ but it's interesting that it works in a minimal example. – Jørgen Feb 24 '12 at 10:56
  • @Jørgen Oops, after doing some reading, I can see that both markups are valid, my bad. I guess I'm used to doing it that way. Without being able to reproduce the problem one can only guess something else on your end is interfering. :P – ShadowScripter Feb 24 '12 at 11:03
  • No problem :) I wonder if it has soemthing to do with timing. I'll post back here if I find a solution myself. Meanwhile I hope someone else care to share some experience on this. – Jørgen Feb 24 '12 at 11:17