it-swarm.com.ru

Как изменить положение всплывающего окна элемента управления jQuery DatePicker

Любая идея, как заставить DatePicker появляться в конце связанного текстового поля вместо непосредственно под ним? Обычно бывает, что текстовое поле находится внизу страницы, а DatePicker перемещается вверх, чтобы учесть это, и полностью покрывает текстовое поле. Если пользователь хочет ввести дату, а не выбрать ее, он не может. Я бы предпочел, чтобы он появлялся сразу после текстового поля, поэтому не имеет значения, как он регулируется по вертикали.

Есть идеи, как управлять позиционированием? Я не видел никаких настроек для виджета, и мне не повезло с настройкой CSS, но я мог что-то упустить.

96
gfrizzle

Принятый ответ на этот вопрос на самом деле не для jQuery UI Datepicker. Чтобы изменить положение DatePicker пользовательского интерфейса jQuery, просто измените .ui-datepicker в файле css. Таким же образом можно изменить размер DatePicker, просто отрегулируйте размер шрифта.

26
jonmc12

Вот что я использую:

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

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

117
Sean CH

Я делаю это прямо в CSS:

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

Все поля ввода даты имеют ширину 100 пикселей. Я также добавил z-index, чтобы календарь также отображался над всплывающими окнами AJAX.

Я не изменяю CSS-файл jquery-ui; Я перегружаю класс в своем основном CSS-файле, чтобы я мог изменить тему или обновить виджет без необходимости повторного ввода моих конкретных модов.

38
Christian Lescuyer

Вот мой вариант выравнивания календаря Datepicker. 

Я думаю, что это довольно приятно, потому что вы можете управлять позиционированием с помощью утилиты jQuery UI Position.

Одно ограничение: требуется jquery.ui.position.js.

Код:

$('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);
    }
})
30
Rost

Вот еще один вариант, который мне подходит, отрегулируйте 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="//code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
<form>
<input class="datepicker" name="date1" type="text">
<input class="datepicker" name="date2" type="text">
</form>

22
Patrick

Это работает для меня:

 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);
15
David Laberge

Во-первых, я думаю, что в объекте datepicker должен быть метод afterShowing, где вы можете изменить позицию после того, как jquery выполнит все свое вуду в методе _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 может нарушить ваш код.

6
monzonj

Мне нужно было расположить указатель даты в соответствии с родительским элементом div, в котором находился мой элемент управления вводом без полей. Для этого я использовал утилиту «position», включенную в ядро ​​пользовательского интерфейса jquery. Я сделал это в событии beforeShow. Как уже отмечали другие, вы не можете установить положение непосредственно в beforeShow, так как код средства выбора даты сбрасывает местоположение после завершения функции beforeShow. Чтобы обойти это, просто установите позицию, используя setInterval. Текущий сценарий завершится, показывая средство выбора даты, а затем код перемещения будет запущен сразу после того, как средство выбора даты станет видимым. Хотя это никогда не должно происходить, если средство выбора даты не отображается через 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);
        }
3
Brett Birschbach

привязать фокус после использования datepicker изменить css виджета datepicker желать помощи

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

я исправил это с помощью своего пользовательского кода jquery.

  1. дал моему полю ввода datepicker класс ".datepicker2"

  2. найти свою текущую позицию сверху и

  3. расположил всплывающее окно с именем класса ".ui-datepicker"

вот мой код.

$('.datepicker2').click(function(){
    var popup =$(this).offset();
    var popupTop = popup.top - 40;
    $('.ui-datepicker').css({
      'top' : popupTop
     });
});

здесь «40» - это мой ожидаемый пиксель, вы можете изменить свой.

2
sh6210

Я взял его из (( Как контролировать позиционирование jQueryUI datepicker ))

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

оно работает !!!

1
masoud Cheragee

исправить проблему с отображением позиции 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();
        }
    }
1
zersina

Они изменили имя класса на ui-datepicker-trigger

Так что это работает в jquery 1.11.x

.ui-datepicker-trigger { 
margin-top:7px;
  margin-left: -30px;
  margin-bottom:0px;
  position:absolute;
  z-index:1000;
}
1
Marc

Очень простая функция jquery.

$(".datepicker").focus(function(event){
                var dim = $(this).offset();
                $("#ui-datepicker-div").offset({
                    top     :   dim.top - 180,
                    left    :   dim.left + 150
                });
            });
1
Harry

Я потратил смехотворное количество времени, пытаясь выяснить эту проблему на нескольких страницах нового сайта, который я разрабатываю, и, похоже, ничего не получалось (включая любое из представленных выше решений, которые я реализовал. Я предполагаю, что jQuery только что изменился все было достаточно, так как им было предложено, чтобы решения больше не работали. Я не знаю. Честно говоря, я не понимаю, почему в интерфейсе jQuery не реализовано что-то простое для настройки, как это кажется довольно большая проблема с календарем, всегда всплывающим в какой-то позиции, значительно дальше от страницы, к которой он прикреплен.

Во всяком случае, я хотел конечное решение, которое было бы достаточно универсальным, чтобы я мог использовать его где угодно, и это будет работать. Я, кажется, наконец пришел к выводу, что избегаю некоторых из более сложных и специфичных для 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. Было бы просто, я знаю. Я так покончил с этой штукой прямо сейчас. Надеюсь, кто-то еще может извлечь выгоду из этого решения.

1
Programmer Dan

Также стоит отметить, что если IE попадет в режим причуд, ваши компоненты пользовательского интерфейса jQuery и другие элементы будут расположены неправильно.

Чтобы убедиться, что вы не попали в режим причуд, убедитесь, что вы правильно установили свой тип документа на последнюю версию HTML5.

<!DOCTYPE html>

Использование переходного делает беспорядок вещей. Надеюсь, это сэкономит кому-то время в будущем.

0
Halfstop
$('.PDatePicker').MdPersianDateTimePicker({
                Placement: 'top',          
            });
0
hamed hossani

Или вы можете использовать событие focus для вашего объекта dateSelect и api позиции вместе. Вы можете поменять местами верхний и нижний и левый угол вправо или в центр (или на самом деле все, что вы хотите от позиции API). Таким образом, вам не нужен интервал или какое-либо безумно сложное решение, и вы можете настроить макет в соответствии со своими потребностями в зависимости от того, где находится ввод.

dateSelect.focus(function () {
    $("#ui-datepicker-div").position({
        my: "left top",
        at: "left bottom",
        of: $(this)
    });
});
0
Taugenichts

Это помещает функциональность в метод с именем 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);
}
0
Brett Weber

В 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;
    },
0
David Moore
.ui-datepicker {-ms-transform: translate(100px,100px); -webkit-transform: translate(100px,100px); transform: translate(100px,100px);}
0
James