Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save mnpenner/4a52366150deaa44d377c872c7d1fda3 to your computer and use it in GitHub Desktop.
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,
};
}
});
@antoiba86
Copy link

antoiba86 commented Oct 11, 2019

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.

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+rect.height,
            left: rect.left
        };
    }
});

@jccapetillo
Copy link

jccapetillo commented Mar 18, 2020

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
        };
    }
});

@staaky
Copy link

staaky commented Aug 24, 2020

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment