How to control positioning of jQueryUI datepicker

The datepicker in jQueryUI renders with a dynamic position. It renders according to its css if there’s enough room for it, but if there isn’t enough window space it tries to render on screen. I need it to stay put and render in the same place every time, independent of the screen position or other circumstances. How can this be done with the jQueryUI datepicker? Other implementations of jQuery datepicker seem to have ways of doing this, but I don’t see a way of doing it for the UI version.

The answer doesn’t seem to be just modifying the css:

.ui-datepicker { width: 17em; padding: .2em .2em 0; (trying top/margin-top/position:relative, etc. here...)}

…since when the datepicker is created it dynamically creates top and left in element style. Haven’t found a way around this yet. One approach I saw is to give something like this in the beforeShow option:

beforeShow: function(input,inst){
                                inst.dpDiv.css({ 
                                   'top': input.offsetHeight+ 'px', 
                                   'left':(input.offsetWidth - input.width)+ 'px'
                                               });
                                }

This has some effect but the top and left properties are still being dynamically set after this is run when the datepicker renders. It’s still trying to render on screen. How do I get it to always render in the same spot? My next step is probably to go into the datepicker guts and start pulling things out. Any ideas?

Note that the answer (for the UI version) is not in:

How to select a dynamic datepicker instance in order to extend it with jQuery

I’m trying to control positioning of a jQuery datepicker element. I like the solution offered at http://stackoverflow.com/questions/1818670/how-to-control-positioning-of-jqueryui-datepicker for overri

How to fix broken JQueryUI Datepicker

I have a JQueryUI datepicker defined as follows: $(function() { $(.visit_date).datepicker({ changeMonth: true, changeYear: true, showButtonPanel: true, dateFormat: yy-mm-dd }); }); The view code

Styling the jQueryUI DatePicker

I am using the jquery datepicker (http://jqueryui.com/demos/datepicker/). The datepicker on the demo page is small and compact. However, when I use the datepicker on my site, the calendar is HUGE. I w

How to make jQueryUI datepicker permanently expanded

I want to make a datepicker which is always expanded; how can I do it?

Disable a jqueryui datepicker

I have a jqueryui datepicker associated with a input text. When i make the input textbox readonly i dont want the datepicker to show up . Is that possible? I would be setting the readonly property to

How to make jqueryUI datepicker submit in a different format than what is being displayed?

I’m working on some internationalization using jQueryUI. I have a DatePicker control on a form that is properly working in the French language. When I select a date, for example August 15, 2012, the D

JqueryUI DatePicker parseDate comparison

I am trying to compare a date in the jqueryui datepicker.beforeShowDay() to establish whether a day is selectable or not. However it doesn’t seem to work. The code is: function (d) { if ((d.getDay() =

Validating jQueryUi DatePicker

I’m having a lot of trouble with a jQueryUI DatePicker. Whenever it loses focus, the background of the TextBox turns a light shade of red (presumably indicating an invalid date). It is doing this even

JQueryUI Datepicker Event

i have 2 input form using jqueryui datepicker: 1. begin date 2. end date what i want is, when i select date from begin date then datepicker on end date only display date after begin date. so it

getting date from JQueryUI Datepicker

I am using JQueryUI datepicker. I am currently using following: $(‘#dtpicker’).datepicker(‘getDate’); to get date from the datepicker. This function by default gets me today’s date if the user has no

Answers

Edit: JaredC gave an updated answer for later versions of jQuery above. Switching accepted answer to that.

Alright, this is a matter of monkeypatching the feature it has of attempting to always render in the viewport since there’s no option provided to enable/disable the feature. Luckily it’s uncoupled and isolated in one function so we can just go in and override it. The following code completely disables that feature only:

$.extend(window.DP_jQuery.datepicker,{_checkOffset:function(inst,offset,isFixed){return offset}});

_checkOffset is called when it’s opening and it does calculations on the offset and returns a new offset if it would otherwise be outside of the view port. This replaces the function body to just pass the original offset right through. Then you can use the beforeShow setting hack and/or the .ui-datepicker css class to put it wherever you want.

Posting this in hopes that it will help others. At least as of v1.8.1 of datepicker, using ‘window.DP_jQuery.datepicker’ no longer works, because the pointer(right term?) now is named with a timestamp of its creation – so for example it would now be ‘window.DP_jQuery_1273700460448’. So now, rather than using the pointer to the datepicker object, refer to it directly like this:

$.extend($.datepicker,{_checkOffset:function(inst,offset,isFixed){return offset}});

Many thanks for the answer below for getting me what I needed.

In your css file, for example:

#ui-datepicker-div {
  position: absolute !important;
  top: auto !important;
  left: auto !important;
}

Your important settings, whatever they are, will override the inline defaults.

here is a more simple solution

var $picker = $( ".myspanclass" ).datepicker(); // span has display: inline-block
$picker.find('.ui-datepicker').css('margin-left', '-50px');

bind focusin after using datepicker change css of datepicker`s widget wish help

$('input.date').datepicker();
$('input.date').focusin(function(){
    $('input.date').datepicker('widget').css({left:"-=127"});
});

earlier i tried giving top, left in beforeShow event of datepicker.js, that’s get override by _showDatePicker method of jquery-ui-custom.js . But after timeout the window its working fine. Below is the code

beforeShow : function(input,inst) {
  var offset = coxjs.select("#" + dpId).offset();
                        var height = coxjs.select("#" + dpId).height();
                        var width = coxjs.select("#" + dpId).width();
                        window.setTimeout(function () {
                              coxjs.select(inst.dpDiv).css({ top: (offset.top + height - 185) + 'px', left: (offset.left + width + 50) + 'px' })
                        }, 1);
}

By default the calendar of the date picker was display to the upper-right of my input box, so the top of it was hidden by my menu bar. Here’s how I positioned the widget (jquery-ui version 1.11.4) very simply (note that ‘ui-datepicker’ is the class name given by jquery-ui):

$(document).ready(function() {
$(".ui-datepicker").css('margin-left', '-50px', 'margin-top', '-50px');
//... 
}

This is quite an old question however I recently ran into an issue similar to this with the jQuery UI Datepicker. We were already using the solution posted by @JaredC above (specifically this code snippet: $.extend($.datepicker,{_checkOffset:function(inst,offset,isFixed){return offset}});) however it would not work for a modal that had an input in which we needed to render a dropdown.

This issue would occur because when scrolling down the page the offset of the input in the modal changes relative to the top of the scrolled page. The resulting behavior would mean that the datepicker would render in a different vertical position depending on how far you scrolled down the page (note: while visible and scrolling the datepicker was already fixed). The solution to this issue (“datepicker input nested within a modal”) is to instead calculate the vertical positioning of the input relative to the view screen and then add the height of the input (allowing the “top” css property of the datepicker to be right below that of the input).

The following snippet is in coffeescript. Instead of returning the regular offset as per @JaredC’s solution we instead obtain the elementId of the input from the ‘inst’ object and then access the object via jquery in order to use it to calculate the input’s distance from the top of the screen relative to the viewport.

# CoffeeScript
$.extend( $.datepicker, { _checkOffset: (inst,offset,isFixed) ->
        offset.top = $("##{inst.id}").offset().top - $(window).scrollTop() + $("##{inst.id}")[0].getBoundingClientRect().height
        offset
    }
)

// JavaScript
$.extend($.datepicker, {
    _checkOffset: function(inst, offset, isFixed) {
        offset.top = $("#" + inst.id).offset().top - $(window).scrollTop() + $("#" + inst.id)[0].getBoundingClientRect().height;
        return offset;
    }
});

The problem I was having is that the datepicker is positioned incorrectly inside fixed elements, such as fancy/lightboxes. For some reason, the datepicker switches into “fixed” positioning mode when this happens, and then the offset calculation becomes incorrect, when absolute positioning would have worked just fine.

However, we can get the correct fixed position with this hack:

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];

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

with jQuery:

beforeShow : function(input,inst){
    var offset = $(input).offset();
    var height = $(input).height();
    window.setTimeout(function () {
        $(inst.dpDiv).css({ top: (offset.top + height) + 'px', left:offset.left + 'px' })
    }, 1);
}

The accepted answer works very well overall.

However, using jQuery UI v1.11.4, I had an issue where the datepicker would position itself away from the input in a modal window (fixed positioning) when the browser window has been scrolled down. I was able to fix this problem editing the accepted answer as follows:

const checkOffset = $.datepicker._checkOffset;

$.extend($.datepicker, {
  _checkOffset: function(inst, offset, isFixed) {
    if(isFixed) {
      return checkOffset.apply(this, arguments);
    } else {
      return offset;
    }
  }
});