Как управлять позиционированием jQueryUI datepicker

Датчик даты в jQueryUI отображает динамическую позицию. Он отображает в соответствии с его css, если для этого достаточно места, но если не хватает оконного пространства, он пытается отобразить на экране. Мне нужно, чтобы он оставался на месте и визуализировался в одном и том же месте каждый раз, независимо от положения экрана или других обстоятельств. Как это можно сделать с помощью jQueryUI datepicker? Другие реализации jQuery datepicker, похоже, имеют способы сделать это, но я не вижу способа сделать это для версии пользовательского интерфейса.

Ответ, похоже, не просто изменяет css:

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

... поскольку, когда создается датапикер, он динамически создает верхний и левый стили элементов. Пока не нашел пути. Один из подходов, который я видел, - это дать что-то подобное в опции beforeShow:

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

Это имеет некоторый эффект, но верхние и левые свойства по-прежнему динамически устанавливаются после того, как это выполняется при отображении datepicker. Он все еще пытается отобразить на экране. Как мне заставить его всегда отображать в одном месте? Следующим шагом, вероятно, является переход к дампикерским кишкам и начало вытаскивать вещи. Любые идеи?

Обратите внимание, что ответ (для версии пользовательского интерфейса) отсутствует:

Ответ 1

Проводя это в надежде, что это поможет другим. По крайней мере, начиная с v1.8.1 datepicker, использование "window.DP_jQuery.datepicker" больше не работает, потому что теперь указатель (правый термин?) Назван временной меткой его создания - так, например, теперь это будет "окно". DP_jQuery_1273700460448. Итак, вместо того, чтобы использовать указатель на объект datepicker, обратитесь к нему прямо следующим образом:

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

Большое спасибо за ответ ниже, чтобы получить мне то, что мне было нужно.

Ответ 2

Изменить: JaredC предоставил обновленный ответ для более поздних версий jQuery выше. Переключение принятого ответа на этот вопрос.

Хорошо, это вопрос monkeypatching функции, которую он пытается всегда визуализировать в окне просмотра, так как нет возможности включить/отключить эту функцию. К счастью, он отсоединен и изолирован одной функцией, поэтому мы можем просто войти и переопределить ее. Следующий код полностью отключает эту функцию:

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

_checkOffset вызывается, когда он открывается, и выполняет вычисления по смещению и возвращает новое смещение, если оно иначе было бы за пределами порта представления. Это заменяет тело функции, чтобы просто передать исходное смещение прямо. Затем вы можете использовать хакерский режим beforeShow и/или класс .ui-datepicker css, чтобы поместить его туда, где хотите.

Ответ 3

связывать focusin после использования datepicker изменить css виджета datepicker пожелать помощи

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

Ответ 4

В вашем файле css, например:

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

Ваши важные настройки, независимо от того, что они есть, переопределяют встроенные значения по умолчанию.

Ответ 5

Раньше я пытался дать top, слева в beforeShow событие datepicker.js, которые получают переопределение методом _showDatePicker jquery-ui-custom.js. Но после таймаута его работа прекрасна. Ниже приведен код
beforeShow : function(input,inst) {
  var offset = js.select("#" + dpId).offset();
                        var height = js.select("#" + dpId).height();
                        var width = js.select("#" + dpId).width();
                        window.setTimeout(function () {
                              js.select(inst.dpDiv).css({ top: (offset.top + height - 185) + 'px', left: (offset.left + width + 50) + 'px' })
                        }, 1);
}

Ответ 6

Это довольно старый вопрос, однако я недавно столкнулся с проблемой, подобной этой, с jQuery UI Datepicker. Мы уже использовали решение, размещенное на @JaredC выше (в частности, этот фрагмент кода: $.extend($.datepicker,{_checkOffset:function(inst,offset,isFixed){return offset}});), однако он не будет работать для модала, у которого был вход, в котором нам нужно было отобразить выпадающее меню.

Эта проблема возникнет, потому что при прокрутке страницы смещение входа в модальном изменении происходит относительно верхней части прокручиваемой страницы. В результате поведение будет означать, что datepicker будет отображаться в другом вертикальном положении в зависимости от того, насколько далеко вы прокручиваете страницу (обратите внимание: в то время как видимые и прокрутки datepicker уже были исправлены). Решение этой проблемы ( "вход datepicker, вложенное в модальный" ) заключается в том, чтобы вместо этого рассчитывать вертикальное позиционирование ввода относительно экрана просмотра, а затем добавлять высоту ввода (позволяя "верхнее" свойство css datepicker быть ниже, чем у входа).

Следующий фрагмент находится в файле coffeescript. Вместо того, чтобы возвращать регулярное смещение в соответствии с решением @JaredC, мы вместо этого получаем elementId ввода из объекта "inst", а затем получаем доступ к объекту через jquery, чтобы использовать его для вычисления входного расстояния от верхней части экрана относительно в окне просмотра.

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

Ответ 7

Проблема, с которой я столкнулась, заключается в том, что datepicker неправильно помещается внутри фиксированных элементов, таких как fancy/lightboxes. По какой-то причине датапикер переключается в "фиксированный" режим позиционирования, когда это происходит, а затем вычисление смещения становится неправильным, когда абсолютное позиционирование будет работать нормально.

Однако мы можем получить правильную фиксированную позицию с этим взломом:

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

Ответ 8

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

Ответ 9

Принятый ответ работает очень хорошо.

Однако, используя jQuery UI v1.11.4, у меня была проблема, когда датпикер отложил себя от ввода в модальном окне (фиксированное позиционирование), когда окно браузера было прокручено вниз. Я смог исправить эту проблему, отредактировав принятый ответ следующим образом:

const checkOffset = $.datepicker._checkOffset;

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

Ответ 10

здесь более простое решение

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

Ответ 11

По умолчанию календарь выбора даты отображался в правом верхнем углу окна ввода, поэтому верхняя часть его была скрыта в моей строке меню. Вот как я позиционировал виджет (jquery-ui version 1.11.4) очень просто (обратите внимание, что "ui-datepicker" - это имя класса, заданное jquery-ui):

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