Как управлять позиционированием 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');
//...
}