it-swarm.com.ru

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

Средство выбора даты в jQueryUI отображается с динамической позицией. Он выполняет рендеринг в соответствии со своим CSS, если для этого достаточно места, но если не хватает места в окне, он пытается отобразить его на экране. Мне нужно, чтобы он всегда оставался на месте и отображался в одном и том же месте, независимо от положения экрана или других обстоятельств. Как это можно сделать с помощью инструмента выбора даты jQueryUI? Другие реализации 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'
                                               });
                                }

Это имеет некоторый эффект, но свойства top и left по-прежнему динамически устанавливаются после того, как они выполняются, когда отображается средство выбора даты. Это все еще пытается сделать на экране. Как мне сделать так, чтобы он всегда отображался в одном и том же месте? Мой следующий шаг, вероятно, состоит в том, чтобы разобраться в интуиции и начать вытаскивать вещи. Есть идеи?

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

33
Purrell

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

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

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

64
JaredC

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

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

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

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

9
Purrell

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

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

с помощью 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);
}
2
Liviu Alexandru Bobocu

Например, в вашем CSS-файле:

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

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

1
Joe Lalgee

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

Тем не менее, мы можем получить правильную фиксированную позицию с помощью этого хака:

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

ранее я пытался задать 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);
}
1
Sudeep
$("first-selector").datepicker().bind('click',function () {
      $("#ui-datepicker-div").appendTo("other-selector");
});

<style>
#ui-datepicker-div {
        position: absolute !important;
        top: auto !important;
        left: auto !important;
        z-index: 99999999 !important;
}
</style>
1
Pardeep Goyal

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

Эта проблема возникает из-за того, что при прокрутке вниз страницы смещение ввода в модальном режиме изменяется относительно верхней части прокручиваемой страницы. Получившееся поведение будет означать, что средство выбора даты будет отображаться в другом вертикальном положении в зависимости от того, как далеко вы прокручивали страницу вниз (примечание: когда видимый и прокручиваемый указатель даты уже исправлен). Решение этой проблемы («ввод DatePicker, вложенный в модальный режим») состоит в том, чтобы вместо этого рассчитать вертикальное расположение ввода относительно экрана просмотра, а затем добавить высоту ввода (позволяя свойству css «top» 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;
    }
});
1
Eric Walsh

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

Однако, используя 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;
    }
  }
});
1
sebsonic2o

Вот как это сработало для меня:

$( "input[name='birthdate']" ).datepicker({
    beforeShow : function(input,inst){
    window.setTimeout(function () {
        $("#ui-datepicker-div").position({ my: "left top", at: "left bottom", of: input });
    }, 1);
    }
});

Чтобы установить его, когда размер экрана изменяется:

$(window).resize(function(){ $("#ui-datepicker-div").position({ my: "left top", at: "left bottom", of: "input[name='birthdate']" }); });
0
obeliksz