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


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

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

20 96

20 ответов:

принятый ответ на этот вопрос на самом деле не для 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'});
    }
});

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

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

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

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

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

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

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

одно ограничение: jquery.пользовательский интерфейс.позиция.Яш требуется.

код:

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

вот еще один вариант, который хорошо работает для меня, отрегулируйте прямоугольник.топ + 40, прямоугольник.слева + 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>

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

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

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

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

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

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

  2. найти его текущее положение сверху и

  3. расположил всплывающее окно, имя класса которого ".пользовательский интерфейс-отмечать"

вот мой код.

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

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

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

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

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

Я потратил смешное количество времени, пытаясь понять эту проблему для нескольких страниц нового сайта, который я разрабатываю, и ничего не сработало (включая любые из различных решений, представленных выше, которые я реализовал. Я предполагаю, что 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());
});

по существу я прикрепляю новый тег стиля к голове до каждого события datepicker "show" (удаление предыдущего, если оно присутствует). Этот метод выполнения вещей позволяет обойти подавляющее большинство проблем, с которыми я столкнулся во время разработки.

протестировано на Chrome, Firefox, Safari и IE>8 (поскольку IE8 не работает хорошо с jsFiddle, и я теряю свой вкус забота о

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

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

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

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

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

$.расширять.$(элемент управления datepicker, { _checkOffset: функция(инст, смещение, isFixed) { возвращает смещение } });

это работает !!!

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

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

<!DOCTYPE html>

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

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

Внутри Jquery.Пользовательский интерфейс просто обновить функции _checkOffset, так что viewheight значение добавляется к смещению.сверху, перед возвратом смещения.

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

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

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