How to change the pop-up position of the jQuery DatePicker control

Any idea how to get the DatePicker to appear at the end of the associated text box instead of directly below it? What tends to happen is that the text box is towards the bottom of the page and the DatePicker shifts up to account for it and totally covers the text box. If the user wants to type the date instead of pick it, they can't. I'd rather have it appear just after the text box so it doesn't matter how it adjusts vertically.

Any idea how to control the positioning? I didn't see any settings for the widget, and I haven't had any luck tweaking the CSS settings, but I could easily be missing something.


Solution 1:

Here's what I'm using:

$('input.date').datepicker({
    beforeShow: function(input, inst) {
        inst.dpDiv.css({
            marginTop: -input.offsetHeight + 'px', 
            marginLeft: input.offsetWidth + 'px'
        });
    }
});

You may also want to add a bit more to the left margin so it's not right up against the input field.

Solution 2:

I do it directly in the CSS:

.ui-datepicker { 
  margin-left: 100px;
  z-index: 1000;
}

My date input fields are all 100px wide. I also added the z-index so the calendar also appears above AJAX popups.

I don't modify the jquery-ui CSS file; I overload the class in my main CSS file, so I can change the theme or update the widget without having to re-enter my specific mods.

Solution 3:

Here is my variation of Datepicker calendar aligning.

I think that it's pretty nice, because you can control positioning via jQuery UI Position util.

One restriction: jquery.ui.position.js required.

Code:

$('input[name=date]').datepicker({
    beforeShow: function(input, inst) {
        // Handle calendar position before showing it.
        // It's not supported by Datepicker itself (for now) so we need to use its internal variables.
        var calendar = inst.dpDiv;

        // Dirty hack, but we can't do anything without it (for now, in jQuery UI 1.8.20)
        setTimeout(function() {
            calendar.position({
                my: 'right top',
                at: 'right bottom',
                collision: 'none',
                of: input
            });
        }, 1);
    }
})