developer tip

jQuery DatePicker 컨트롤의 팝업 위치를 변경하는 방법

copycodes 2020. 8. 14. 07:54
반응형

jQuery DatePicker 컨트롤의 팝업 위치를 변경하는 방법


DatePicker가 연결된 텍스트 상자 바로 아래 대신 끝에 표시되도록하는 방법을 알고 계십니까? 발생하는 경향은 텍스트 상자가 페이지 하단에 있고 DatePicker가이를 설명하기 위해 위로 이동하고 텍스트 상자를 완전히 덮는 것입니다. 사용자가 날짜를 선택하는 대신 입력하려는 경우에는 입력 할 수 없습니다. 차라리 텍스트 상자 바로 뒤에 나타나도록하여 세로로 조정하는 방법은 중요하지 않습니다.

위치를 제어하는 ​​방법을 아십니까? 나는 위젯에 대한 설정을 보지 못했고 CSS 설정을 조정하지 않았지만 쉽게 무언가를 놓칠 수 있습니다.


이 질문에 대한 대답은 실제로 jQuery UI Datepicker가 아닙니다. jQuery UI Datepicker의 위치를 ​​변경하려면 css 파일에서 .ui-datepicker를 수정하면됩니다. 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 팝업 위에 표시됩니다.

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

여기 저에게 잘 맞는 또 다른 변형이 있습니다. 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>


이것은 나를 위해 작동합니다.

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

먼저 afterShowingjquery가 _showDatepicker메서드 에서 모든 부두를 수행 한 후에 위치를 변경할 수있는 datepicker 개체에 메서드 가 있어야한다고 생각합니다 . 또한라는 매개 변수 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
    }
});

그러나의 내부 구현이 변경되면 _showDatepicker코드가 손상 될 수 있으므로 Jquery-ui 업데이트에주의 하십시오.


경계없는 입력 컨트롤이있는 부모 div에 따라 datepicker를 배치해야했습니다. 이를 위해 jquery UI 코어에 포함 된 "position"유틸리티를 사용했습니다. beforeShow 이벤트에서이 작업을 수행했습니다. 다른 사람들이 위에서 언급했듯이 datepicker 코드는 beforeShow 함수를 마친 후 위치를 재설정하므로 beforeShow에서 직접 위치를 설정할 수 없습니다. 이를 우회하려면 setInterval을 사용하여 위치를 설정하기 만하면됩니다. 현재 스크립트가 완료되어 datepicker가 표시되고, datepicker가 표시된 직후 위치 변경 코드가 실행됩니다. 절대 발생해서는 안되지만, .5 초 후에 datepicker가 표시되지 않으면 코드는 포기하고 간격을 지울 수있는 안전 장치가 있습니다.

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

datepicker 사용 후 focusin 바인딩 datepicker 위젯의 CSS 변경 희망 도움말

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

내 사용자 지정 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"은 내 예상 픽셀입니다.


표시 위치 문제 수정 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
                });
            });

I spent a ridiculous amount of time trying to figure this problem out for several pages of a new site I'm developing and nothing seemed to work (including any of the various solutions presented above that I implemented. I'm guessing jQuery has just changed things up enough since they were suggested that the solutions dont' work any longer. I don't know. Honestly, I don't understand why there isn't something simple implemented into the jQuery ui to configure this, as it seems to be a fairly large issue with the calendar always popping up at some position considerably far down the page from the input to which it is attached.

Anyhow, I wanted an end solution that was generic enough that I could use it anywhere and it would work. I seem to have finally come to a conclusion that avoids some of the more complicated and jQuery-code-specific answers above:

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

Essentially I attach a new style tag to the head prior to every datepicker "show" event (deleting the previous one, if present). This method of doing things gets around a large majority of the issues that I ran into during development.

Tested on Chrome, Firefox, Safari, and IE>8 (as IE8 doesn't work well with jsFiddle and I'm losing my gusto for caring about

I know that this is a mix of jQuery and javascript contexts, but at this point I just don't want to put the effort into converting it to jQuery. Would be simple, I know. I'm so done with this thing right now. Hope someone else can benefit from this solution.


They changed the classname to ui-datepicker-trigger

So this works in jquery 1.11.x

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

I took it from ((How to control positioning of jQueryUI datepicker))

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

it works !!!


It's also worth noting that if IE falls into quirks mode, your jQuery UI components, and other elements, will be positioned incorrectly.

To make sure you don't fall into quirks mode, make sure you set your doctype correctly to the latest HTML5.

<!DOCTYPE html>

Using transitional makes a mess of things. Hopefully this will save someone some time in the future.


This puts the functionality into a method named function, allowing for your code to encapsulate it or for the method to be made a jquery extension. Just used on my code, works perfectly

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

Within Jquery.UI, just update the _checkOffset function, so that viewHeight is added to offset.top, before offset is returned.

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

Or you can use the focus event on your dateSelect object and position api together. You can swap top and bottom and left for right or center (or really anything you want from the position api). This way you don't need an interval or any insanely complex solution and you can configure the layout to suit your needs depending on where the input is.

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

$('.PDatePicker').MdPersianDateTimePicker({
                Placement: 'top',          
            });

참고URL : https://stackoverflow.com/questions/662220/how-to-change-the-pop-up-position-of-the-jquery-datepicker-control

반응형