How to change jquery ui datepicker position?

May be an old question, but ran into the problem myself just today and could not get other suggestions to work. Fixed it alternatively (using .click(function(){}) and wanted to add my two cents.

I have an input field with the id sDate which, when clicked, displays the datepicker.

What I did to solve the problem was add a click routine to the #sDate field.

$('#sDate').click(function(){  //CHANGE sDate TO THE ID OF YOUR INPUT FIELD 
    var pTop = '10px';  //CHANGE TO WHATEVER VALUE YOU WANT FOR TOP POSITIONING
    var pLeft = '10px';  //CHANGE TO WHATEVER VALUE YOU WANT FOR LEFT POSITIONING
    $('#ui-datepicker-div').css({'left':pLeft, 'top':pTop});
});

Sure it is. As there's always only one datepicker active, you can select active datepicker with:

var $datepicker = $('#ui-datepicker-div');

and change its position:

$datepicker.css({
    top: 10,
    left: 10
});

EDIT

Whoah, tricky one. If you set top or left position in beforeShow, it gets overriden again by datepicker plugin. You have to put css changes in a setTimeout:

$("#datepicker").datepicker({
    beforeShow: function (input, inst) {
        setTimeout(function () {
            inst.dpDiv.css({
                top: 100,
                left: 200
            });
        }, 0);
    }
});

DEMO: http://jsfiddle.net/BWfwf/4/

Explanation about setTimeout(function () {}, 0): Why is setTimeout(fn, 0) sometimes useful?


If you get really stuck you can edit your jquery-ui-[version].custom.js. The function that controls the position where the calender will appear is:

_findPos: function(obj) { var position, inst = this._getInst(obj), isRTL = this._get(inst, "isRTL");

    while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
        obj = obj[isRTL ? "previousSibling" : "nextSibling"];
    }

    position = $(obj).offset();
    return [position.left, position.top];
},

I have some custom code that uses a CSS3 transformation to zoom the page in or out based on its width. This throws out the screen coordinates that the calendar widget relies on. I added some custom code to the _findPos to detect and handle the zoom level. Modified code looks like this:

_findPos: function(obj) {
    var position,
        inst = this._getInst(obj),
        isRTL = this._get(inst, "isRTL");

    while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
        obj = obj[isRTL ? "previousSibling" : "nextSibling"];
    }

    position = $(obj).offset();
    /* Custom Code for Zoom */
    var zoomLevel = 1;
    var minW = 1024;
    if ($(window).width() > minW)
               { zoomLevel = $(window).width() / minW;}
    return [position.left, position.top/zoomLevel];
},

Tags:

Jquery Ui