Search and Top Navigation
#8592 closed bug (notabug)
Opened September 22, 2012 12:55PM UTC
Closed September 22, 2012 07:28PM UTC
Last modified October 19, 2012 04:41PM UTC
Datepicker disappears upon scroll
Reported by: | glthomas224 | Owned by: | |
---|---|---|---|
Priority: | minor | Milestone: | 1.9.0 |
Component: | ui.datepicker | Version: | 1.8.23 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
This bug is very easy to reproduce. Simply go to the jquery example at http://jqueryui.com/demos/datepicker/ and then click on the text input field to make the datepicker appear. Now if the user attempts to scroll their browser window the datepicker will disappear. Naturally the user would think that in order to get the datepicker to reappear they would need to click into the input form field again. However this only works if the user causes the input field to blur first like by clicking outside of the input field. Only then can the datepicker be made to reappear.
I've discovered a way to fix this though. On line 843 of the jquery.ui.datepicker.js file resides the _checkExternalClick: function. Within that function is the line:
$.datepicker._hideDatepicker();
Simply wrap that line so that it looks like this:
$('html').click(function () {
$.datepicker._hideDatepicker();
});
the whole function should now look like this:
_checkExternalClick: function (event) {
if (!$.datepicker._curInst)
return;
var $target = $(event.target),
inst = $.datepicker._getInst($target[0]);
if ((($target[0].id != $.datepicker._mainDivId &&
$target.parents('#' + $.datepicker._mainDivId).length == 0 &&
!$target.hasClass($.datepicker.markerClassName) &&
!$target.hasClass($.datepicker._triggerClass) &&
$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI)))||($target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst != inst))
$('html').click(function () {
$.datepicker._hideDatepicker();
});
return;
},
Now when the user clicks on the scroll bar of a browser it won't inadvertently close the datepicker because the scrollbar is considered to be outside the "html" object. Voila! I tested in IE, Chrome, and FireFox. Enjoy. Hopefully you can patch this into the next release!
Attachments (0)
Change History (3)
Changed September 22, 2012 04:50PM UTC by comment:1
_comment0: | After some further testing I determined that this is not a fix to the bug that I described. I have continued to try and patch this bug and here is what I have come up with for a solution. It's kind of ugly but there may be some more elegant ways to achieve the desired behavior. Essentially we want the datepicker to stay visible if we scroll using the mouse or keyboard. Clicking on the scrollbar causes the datepicker to disappear. \ \ In the code I pasted above, replace this: \ $('html').click(function () { \ $.datepicker._hideDatepicker(); \ }); \ \ with the following segment of code: \ if (!$target.is('html')) { \ $.datepicker._hideDatepicker(); \ } \ \ Once this is done, clicking on the browser scrollbar while the datepicker is visible will not hide the datepicker. However any space on the page between the body edge and the window edge is indistinguishable from the scrollbar since that space is considered to be an object of HTMLhtmlElement. The scroll bar is also considered to be an object of HTMLhtmlElement. So by creating a div container that fills this extra space between the body edge and the window edge the only thing left that the user can click that is considered to be an object of HTMLhtmlElement is the scrollbar. So here is the extra code needed to do this. \ \ After the <body> tag on your page add: \ <div id="underneath" style="position:absolute; width:0px; height:0px; z-index:-10000; top:0; overflow:hidden; background-color:transparent;"></div> \ \ In your style sheet or within your <style> tag add this: \ html{overflow-x:hidden} \ \ Finally just prior to the </body> tag add the following script \ <script type="text/javascript"> \ jq171('#underneath').css('height', jq171(document).height() + 'px'); \ jq171('#underneath').css('width', jq171(window).width() + 'px'); \ jq171('#underneath').css('left', "0"); \ \ jq171(window).resize(function () { \ if (jq171(window).width() < jq171('body').width()) { \ jq171('html').css('overflow-x', 'scroll'); \ } \ else { \ jq171('html').css('overflow-x', 'hidden'); \ } \ jq171('#underneath').css('width', jq171(window).width() + 'px'); \ }); \ </script> \ \ Hopefully someone can come up with a more elegant solution, but this gets the job done for my needs. \ → 1348332995137569 |
---|
Changed September 22, 2012 07:28PM UTC by comment:2
resolution: | → invalid |
---|---|
status: | new → closed |
The datepicker should not stay open while the user scrolls.
After some further testing I determined that this is not a fix to the bug that I described. I have continued to try and patch this bug and here is what I have come up with for a solution. It's kind of ugly but there may be some more elegant ways to achieve the desired behavior. Essentially we want the datepicker to stay visible if we scroll using the mouse or keyboard. Clicking on the scrollbar causes the datepicker to disappear.
In the code I pasted above, replace this:
$('html').click(function () {
$.datepicker._hideDatepicker();
});
with the following segment of code:
if (!$target.is('html')) {
$.datepicker._hideDatepicker();
}
Once this is done, clicking on the browser scrollbar while the datepicker is visible will not hide the datepicker. However any space on the page between the body edge and the window edge is indistinguishable from the scrollbar since that space is considered to be an object of HTMLhtmlElement. The scroll bar is also considered to be an object of HTMLhtmlElement. So by creating a div container that fills this extra space between the body edge and the window edge the only thing left that the user can click that is considered to be an object of HTMLhtmlElement is the scrollbar. So here is the extra code needed to do this.
After the <body> tag on your page add:
<div id="underneath" style="position:absolute; width:0px; height:0px; z-index:-10000; top:0; overflow:hidden; background-color:transparent;"></div>
In your style sheet or within your <style> tag add this:
html{overflow-x:hidden}
Finally just prior to the </body> tag add the following script:
<script type="text/javascript">
jq171('#underneath').css('height', jq171(document).height() + 'px');
jq171('#underneath').css('width', jq171(window).width() + 'px');
jq171('#underneath').css('left', "0");
jq171(window).resize(function () {
if (jq171(window).width() < jq171('body').width()) {
jq171('html').css('overflow-x', 'scroll');
}
else {
jq171('html').css('overflow-x', 'hidden');
}
jq171('#underneath').css('width', jq171(window).width() + 'px');
});
</script>
Hopefully someone can come up with a more elegant solution, but this gets the job done for my needs.