Любая идея, как заставить DatePicker появляться в конце связанного текстового поля, а не прямо под ним? То, что имеет тенденцию, состоит в том, что текстовое поле находится в нижней части страницы, а DatePicker сдвигается, чтобы учесть его и полностью покрывает текстовое поле. Если пользователь хочет ввести дату, а не выбрать ее, они не смогут. Я предпочел бы, чтобы он появился сразу после текстового поля, поэтому не имеет значения, как он настраивается по вертикали.
Любая идея, как управлять позиционированием? Я не видел никаких настроек для виджета, и мне не повезло с настройкой настроек CSS, но я мог легко что-то упустить.
Принятый ответ для этого вопроса на самом деле не для jQuery UI Datepicker. Чтобы изменить положение jQuery UI Datepicker, просто измените параметр .ui-datepicker в файле css. Размер Datepicker также можно изменить таким образом, просто отрегулируйте размер шрифта.
Вот что я использую:
$('input.date').datepicker({
beforeShow: function(input, inst)
{
inst.dpDiv.css({marginTop: -input.offsetHeight + 'px', marginLeft: input.offsetWidth + 'px'});
}
});
Вы также можете добавить немного больше в левое поле, чтобы оно не соответствовало поля ввода.
$(this).position(my:'left top', at:'left bottom', of:'#altField')
(так как я использую опцию altField
для отображения)
Я делаю это непосредственно в CSS:
.ui-datepicker {
margin-left: 100px;
z-index: 1000;
}
Мои поля ввода даты имеют ширину 100 пикселей. Я также добавил z-индекс, поэтому календарь также появляется над всплывающими окнами AJAX.
Я не изменяю файл jquery-ui CSS; Я перегружаю класс в моем основном файле CSS, поэтому я могу изменить тему или обновить виджет, не переписывая свои конкретные моды.
Вот мой вариант выравнивания календаря Datepicker.
Я думаю, что это довольно хорошо, потому что вы можете управлять позиционированием через jQuery UI Position util.
Одно ограничение: требуется jquery.ui.position.js.
код:
$('input[name=date]').datepicker({
beforeShow: function(input, inst) {
// Handle calendar position before showing it.
// It 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);
}
})
Вот еще один вариант, который хорошо работает для меня, отрегулируйте rect.top + 40, rect.left + 0 в соответствии с вашими потребностями:
$(".datepicker").datepicker({
changeMonth: true,
changeYear: true,
dateFormat: 'mm/dd/yy',
beforeShow: function (input, inst) {
var rect = input.getBoundingClientRect();
setTimeout(function () {
inst.dpDiv.css({ top: rect.top + 40, left: rect.left + 0 });
}, 0);
}
});
<link rel="stylesheet" href="/jquery-ui.css">
<script src="/jquery-1.10.2.js"></script>
<script src="/jquery-ui.js"></script>
<form>
<input class="datepicker" name="date1" type="text">
<input class="datepicker" name="date2" type="text">
</form>
Это работает для меня:
beforeShow: function(input, inst) {
var cal = inst.dpDiv;
var top = $(this).offset().top + $(this).outerHeight();
var left = $(this).offset().left;
setTimeout(function() {
cal.css({
'top' : top,
'left': left
});
}, 10);
Сначала я думаю, что в объекте datepicker должен быть метод afterShowing
, где вы могли бы изменить позицию после того, как jquery выполнил все его voodoo в методе _showDatepicker
. Кроме того, желателен параметр с именем preferedPosition
, поэтому вы можете установить его, а jquery изменить его, если диалог отображается за пределами области просмотра.
Там есть "трюк", чтобы сделать это последнее. Если вы изучите метод _showDatepicker
, вы увидите использование частной переменной $.datepikcer._pos
. Эта переменная будет настроена, если никто ее не установил раньше. Если вы измените эту переменную перед отображением диалога, Jquery возьмет его и попытается выделить диалог в этой позиции, и если он отобразится вне экрана, он отрегулирует его, чтобы убедиться, что он виден. Звучит неплохо, а?
Проблема: _pos
является закрытым, но если вы не возражаете против этого. Вы можете:
$('input.date').datepicker({
beforeShow: function(input, inst)
{
$.datepicker._pos = $.datepicker._findPos(input); //this is the default position
$.datepicker._pos[0] = whatever; //left
$.datepicker._pos[1] = whatever; //top
}
});
Но будьте осторожны с обновлениями JQuery-ui, потому что изменение внутренней реализации _showDatepicker
может нарушить ваш код.
Мне нужно было расположить datepicker в соответствии с родительским div, в котором находился мой входной контроль без полей. Для этого я использовал служебную программу "position", включенную в ядро jQuery jquery. Я сделал это в событии beforeShow. Как отмечалось выше, вы не можете установить позицию непосредственно в beforeShow, так как код datepicker будет reset местоположением после завершения функции beforeShow. Чтобы обойти это, просто установите позицию, используя setInterval. Текущая script завершится, показывая datepicker, а затем код перестановки будет запускаться сразу же после просмотра даты. Хотя это никогда не должно происходить, если datepicker не отображается через 0,5 секунды, код имеет отказоустойчивость, чтобы отказаться и очистить интервал.
beforeShow: function(a, b) {
var cnt = 0;
var interval = setInterval(function() {
cnt++;
if (b.dpDiv.is(":visible")) {
var parent = b.input.closest("div");
b.dpDiv.position({ my: "left top", at: "left bottom", of: parent });
clearInterval(interval);
} else if (cnt > 50) {
clearInterval(interval);
}
}, 10);
}
связывать focusin после использования datepicker изменить css виджета datepicker пожелать помощи
$('input.date').datepicker();
$('input.date').focusin(function(){
$('input.date').datepicker('widget').css({left:"-=127"});
});
i исправил его своим пользовательским кодом jquery.
предоставил поле ввода datepicker классу ".datepicker2"
найдите текущую позицию сверху и
позиционирует всплывающее окно, имя класса которого .ui-datepicker "
вот мой код.
$('.datepicker2').click(function(){
var popup =$(this).offset();
var popupTop = popup.top - 40;
$('.ui-datepicker').css({
'top' : popupTop
});
});
здесь "40" - это мой ожидаемый пиксель, вы можете изменить его своим.
Я взял это из ((Как управлять позиционированием jQueryUI datepicker))
$. extend ($. datepicker, {_checkOffset: function (inst, offset, isFixed) {return offset}});
он работает!!!
Они изменили имя класса на ui-datepicker-trigger
Итак, это работает в jquery 1.11.x
.ui-datepicker-trigger {
margin-top:7px;
margin-left: -30px;
margin-bottom:0px;
position:absolute;
z-index:1000;
}
Я потратил нелепое время на то, чтобы понять эту проблему для нескольких страниц нового сайта, который я разрабатываю, и ничего не работало (включая любые из представленных выше решений, которые я реализовал. Я предполагаю jQuery только что изменил ситуацию, так как они предложили, чтобы решения не работали дольше. Я не знаю. Честно говоря, я не понимаю, почему в jQuery ui нет ничего простого, чтобы настроить это, поскольку это кажется довольно большой проблемой, когда календарь всегда появляется в некоторой позиции значительно далеко от страницы со входа, к которому он прикреплен.
Во всяком случае, я хотел, чтобы конечное решение было достаточно общим, чтобы я мог использовать его где угодно, и это сработает. Я, кажется, наконец пришел к выводу, что избегает некоторых более сложных и jQuery-специфичных для кода ответов выше:
jsFiddle: http://jsfiddle.net/mu27tLen/
HTML:
<input type="text" class="datePicker" />
JS:
positionDatePicker= function(cssToAdd) {
/* Remove previous positioner */
var oldScript= document.getElementById('datePickerPosition');
if(oldScript) oldScript.parentNode.removeChild(oldScript);
/* Create new positioner */
var newStyle= document.createElement("style");
newStyle.type= 'text/css';
newStyle.setAttribute('id', 'datePickerPostion');
if(newStyle.styleSheet) newStyle.styleSheet.cssText= cssToAdd;
else newStyle.appendChild(document.createTextNode(cssToAdd));
document.getElementsByTagName("head")[0].appendChild(newStyle);
}
jQuery(document).ready(function() {
/* Initialize date picker elements */
var dateInputs= jQuery('input.datePicker');
dateInputs.datepicker();
dateInputs.datepicker('option', {
'dateFormat' : 'mm/dd/yy',
'beforeShow' : function(input, inst) {
var bodyRect= document.body.getBoundingClientRect();
var rect= input.getBoundingClientRect();
positionDatePicker('.page #ui-datepicker-div{z-index:100 !important;top:' + (rect.top - bodyRect.top + input.offsetHeight + 2) + 'px !important;}');
}
}).datepicker('setDate', new Date());
});
По существу, я прикрепляю новый тег стиля к голове до каждого события showpicker "show" (удаляя предыдущий, если есть). Этот способ делать что-то происходит вокруг большого количества проблем, с которыми я столкнулся во время разработки.
Протестировано в Chrome, Firefox, Safari и IE > 8 (так как IE8 не работает с jsFiddle, и я теряю удовольствие от заботы
Я знаю, что это сочетание jQuery и javascript-контекстов, но на данный момент я просто не хочу прикладывать усилия для преобразования его в jQuery. Было бы просто, я знаю. Я так поступил с этой штукой прямо сейчас. Надеюсь, что кто-то может воспользоваться этим решением.
Исправить проблему с отображаемой позицией daterangepicker.jQuery.js
//Original Code
//show, hide, or toggle rangepicker
function showRP() {
if (rp.data('state') == 'closed') {
rp.data('state', 'open');
rp.fadeIn(300);
options.onOpen();
}
}
//Fixed
//show, hide, or toggle rangepicker
function showRP() {
rp.parent().css('left', rangeInput.offset().left);
rp.parent().css('top', rangeInput.offset().top + rangeInput.outerHeight());
if (rp.data('state') == 'closed') {
rp.data('state', 'open');
rp.fadeIn(300);
options.onOpen();
}
}
Здесь достаточно:
$(".date").datepicker({
beforeShow: function(input, {
inst.dpDiv.css({
marginLeft: input.offsetWidth + "px"
});
}
});
.ui-datepicker {-ms-transform: translate(100px,100px); -webkit-transform: translate(100px,100px); transform: translate(100px,100px);}
Очень простая функция jquery.
$(".datepicker").focus(function(event){
var dim = $(this).offset();
$("#ui-datepicker-div").offset({
top : dim.top - 180,
left : dim.left + 150
});
});
Внутри Jquery.UI просто обновите функцию _checkOffset, так что viewHeight добавляется к offset.top, прежде чем возвращается смещение.
_checkOffset: function(inst, offset, isFixed) {
var dpWidth = inst.dpDiv.outerWidth(),
dpHeight = inst.dpDiv.outerHeight(),
inputWidth = inst.input ? inst.input.outerWidth() : 0,
inputHeight = inst.input ? inst.input.outerHeight() : 0,
viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : ($(document).scrollTop()||document.body.scrollTop));
offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? ($(document).scrollTop()||document.body.scrollTop) : 0;
// now check if datepicker is showing outside window viewport - move to a better place if so.
offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
Math.abs(offset.left + dpWidth - viewWidth) : 0);
offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
Math.abs(dpHeight + inputHeight) : 0);
**offset.top = offset.top + viewHeight;**
return offset;
},
Это помещает функциональность в метод с именем function, позволяя вашему коду инкапсулировать его или для того, чтобы метод стал расширением jquery. Просто используется для моего кода, отлично работает
var nOffsetTop = /* whatever value, set from wherever */;
var nOffsetLeft = /* whatever value, set from wherever */;
$(input).datepicker
(
beforeShow : function(oInput, oInst)
{
AlterPostion(oInput, oInst, nOffsetTop, nOffsetLeft);
}
);
/* can be converted to extension, or whatever*/
var AlterPosition = function(oInput, oItst, nOffsetTop, nOffsetLeft)
{
var divContainer = oInst.dpDiv;
var oElem = $(this);
oInput = $(oInput);
setTimeout(function()
{
divContainer.css
({
top : (nOffsetTop >= 0 ? "+=" + nOffsetTop : "-=" + (nOffsetTop * -1)),
left : (nOffsetTop >= 0 ? "+=" + nOffsetLeft : "-=" + (nOffsetLeft * -1))
});
}, 10);
}
Также стоит отметить, что если IE попадет в режим причуд, ваши компоненты jQuery UI и другие элементы будут неправильно установлены.
Чтобы убедиться, что вы не попали в режим quirks, убедитесь, что вы правильно настроили свой doctype на последний HTML5.
<!DOCTYPE html>
Использование перехода делает беспорядок вещей. Надеюсь, это спасет кого-то в будущем.