-
-
Save mnpenner/4a52366150deaa44d377c872c7d1fda3 to your computer and use it in GitHub Desktop.
const checkOffset = $.datepicker._checkOffset; | |
$.extend($.datepicker, { | |
_checkOffset: function(inst, offset, isFixed) { | |
if(!isFixed) { | |
return checkOffset.apply(this, arguments); | |
} | |
let isRTL = this._get(inst, "isRTL"); | |
let obj = inst.input[0]; | |
// copied from Datepicker._findPos (node_modules/jquery-ui/datepicker.js) | |
while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) { | |
obj = obj[isRTL ? "previousSibling" : "nextSibling"]; | |
} | |
let rect = obj.getBoundingClientRect(); | |
return { | |
top: rect.top, | |
left: rect.left, | |
}; | |
} | |
}); |
Thank you very much for this code,
I slightly modified the code to cater my issue where if the input box is at the bottom of the modal, the displayed date time picker is still showing up on the lower part of the input, the date time picker will get cut off the screen, and scrolling doesn't fix the issue.
The modification is adding validation for the top, where if the top + picker's height is greater than the view height, I will have to deduct position top with the picker's height. please feel free to update my code if you find any possible bug/issue. Thanks~!
`
const checkOffset = $.datepicker._checkOffset;
$.extend($.datepicker, {
_checkOffset: function (inst, offset, isFixed) {
if (!isFixed) {
return checkOffset.apply(this, arguments);
}
let isRTL = this._get(inst, "isRTL");
let obj = inst.input[0];
// copied from Datepicker._findPos (node_modules/jquery-ui/datepicker.js)
while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
obj = obj[isRTL ? "previousSibling" : "nextSibling"];
}
let rect = obj.getBoundingClientRect();
// copied from Datepicker._checkOffset
var viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()),
dpHeight = inst.dpDiv.outerHeight();
return {
// added validation for when the date picker is displayed at the bottom
top: viewHeight < rect.top + rect.height + dpHeight ? rect.top - dpHeight : rect.top + rect.height,
left: rect.left
};
}
});
I’ve looked Into this to find the root of the problem, since I wanted to keep the original repositioning of the datepicker intact. The snippets shown here remove horizontal repositioning. The issue seems to be checkOffset
trying compare two differently calculated offsets. In my case that caused positioning to bork out on bordered inputs within a fixed container after scrolling the page.
It turned out to be a 1 line fix in jQuery UI. Here is the pull request: jquery/jquery-ui#1935
Hopefully it’ll also fix your usecase. If it does drop a line in the pull request to confirm, it’ll help get it merged.
Hello, your script saved my life. But I made a little correction because it is necessary to take into account the height of the input.