wake-up-neo.com

So steuern Sie die Positionierung von jQueryUI Datepicker

Der Datepicker in jQueryUI wird mit einer dynamischen Position dargestellt. Es wird entsprechend seiner CSS wiedergegeben, wenn genügend Platz dafür vorhanden ist. Wenn jedoch nicht genügend Fensterplatz vorhanden ist, versucht es auf dem Bildschirm zu rendern. Ich brauche es, um immer an derselben Stelle zu bleiben und zu rendern, unabhängig von der Bildschirmposition oder anderen Umständen. Wie kann das mit dem jQueryUI Datepicker gemacht werden? Andere Implementierungen von jQuery Datepicker scheinen dies zu tun, aber ich sehe keine Möglichkeit, dies für die UI-Version zu tun. 

Die Antwort scheint nicht nur das CSS zu ändern:

.ui-datepicker { width: 17em; padding: .2em .2em 0; (trying top/margin-top/position:relative, etc. here...)}

... seit der Datumsauswahl erstellt wird, werden dynamisch oben und links im Elementstil erstellt. Habe noch keinen Ausweg gefunden. Ein Ansatz, den ich gesehen habe, ist, so etwas in der beforeShow-Option anzugeben:

beforeShow: function(input,inst){
                                inst.dpDiv.css({ 
                                   'top': input.offsetHeight+ 'px', 
                                   'left':(input.offsetWidth - input.width)+ 'px'
                                               });
                                }

Dies hat einige Auswirkungen, aber die Eigenschaften "top" und "left" werden weiterhin dynamisch festgelegt, nachdem dies ausgeführt wurde, wenn der Datepicker dargestellt wird. Es wird immer noch versucht, auf dem Bildschirm zu rendern. Wie bekomme ich es, immer an derselben Stelle zu rendern? Mein nächster Schritt ist wahrscheinlich, in die Dattelpicker zu gehen und Dinge herauszuziehen. Irgendwelche Ideen?

Beachten Sie, dass die Antwort (für die UI-Version) nicht lautet:

33
Purrell

Wenn Sie dies veröffentlichen, hofft es, dass es anderen helfen wird. Zumindest ab Version 1.8.1 von datepicker funktioniert die Verwendung von 'window.DP_jQuery.datepicker' nicht mehr, da der Zeiger (rechter Begriff?) Jetzt mit einem Zeitstempel seiner Erstellung benannt wird - also zum Beispiel 'window'. DP_jQuery_1273700460448 '. Verweisen Sie also, anstatt den Zeiger auf das Datepicker-Objekt zu verwenden, direkt wie folgt:

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

Vielen Dank für die Antwort unten, dass Sie mir das gebracht haben, was ich brauchte.

64
JaredC

Edit: JaredC gab eine aktualisierte Antwort für spätere jQuery-Versionen. Akzeptierte Antwort darauf wechseln.

In Ordnung, dies ist eine Frage des Monkeypatching der Funktion, die versucht wird, immer im Ansichtsfenster zu rendern, da keine Option zum Aktivieren/Deaktivieren der Funktion bereitgestellt wird. Glücklicherweise ist es in einer Funktion entkoppelt und isoliert, sodass wir einfach hineingehen und es überschreiben können. Der folgende Code deaktiviert nur diese Funktion vollständig:

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

_checkOffset wird beim Öffnen aufgerufen und berechnet den Versatz und gibt einen neuen Versatz zurück, wenn er sich außerhalb des Ansichtsports befinden würde. Dadurch wird der Funktionskörper ersetzt, um den ursprünglichen Versatz einfach durchzulassen. Dann können Sie den BeforeShow-Einstellungshack und/oder die .ui-datepicker-Klasse css verwenden, um ihn an beliebiger Stelle abzulegen.

9
Purrell

binden Sie den Fokus nach der Verwendung von datepicker

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

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

In Ihrer CSS-Datei zum Beispiel:

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

Ihre wichtigen Einstellungen überschreiben die Inline-Vorgaben.

1
Joe Lalgee

Das Problem, das ich hatte, ist, dass der Datepicker innerhalb fester Elemente, wie z. B. Phantasie/Leuchtkästen, falsch positioniert ist. Aus irgendeinem Grund wechselt der Datepicker in diesen Fall in den "festen" Positioniermodus. Die Offsetberechnung wird dann falsch, wenn die absolute Positionierung gut funktioniert hätte.

Mit diesem Hack können wir jedoch die korrekte feste Position erhalten:

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

früher habe ich versucht, top zu geben, bevor das Ereignis in showShicker.js enthalten ist. ... Aber nach einer Zeitüberschreitung funktioniert das Fenster gut. Unten ist der Code

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

Dies ist eine ziemlich alte Frage, aber ich habe kürzlich ein ähnliches Problem mit dem jQuery UI Datepicker gefunden. Wir haben bereits die oben von @JaredC veröffentlichte Lösung verwendet (insbesondere dieses Code-Snippet: $.extend($.datepicker,{_checkOffset:function(inst,offset,isFixed){return offset}});). Dies funktioniert jedoch nicht für Modalitäten, die einen Input enthalten, in den wir ein Dropdown-Objekt rendern mussten.

Dieses Problem tritt auf, weil beim Verschieben der Seite der Versatz der Eingabe in den modalen Änderungen relativ zum oberen Rand der gescrollten Seite geändert wird. Das resultierende Verhalten würde bedeuten, dass der Datepicker in einer anderen vertikalen Position gerendert wird, je nachdem, wie weit Sie die Seite nach unten gescrollt haben (Hinweis: Während sichtbar und ein Bildlauf durchgeführt wurde, war der Datepicker bereits behoben). Die Lösung für dieses Problem ("Datepicker-Eingabe in einem Modal verschachtelt") besteht darin, stattdessen die vertikale Position der Eingabe relativ zum Anzeigebildschirm zu berechnen und dann die Höhe der Eingabe hinzuzufügen (wobei die "obere" css-Eigenschaft des Datepickers verwendet wird direkt unter dem der Eingabe liegen). 

Der folgende Ausschnitt ist in Kaffeescript. Statt den regulären Versatz per @ JaredCs Lösung zurückzugeben, rufen wir stattdessen die elementId der Eingabe vom 'inst'-Objekt ab und greifen dann über jquery auf das Objekt zu, um daraus den Abstand der Eingabe vom oberen Rand des Bildschirms relativ zu berechnen der Viewport. 

# 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

Die akzeptierte Antwort funktioniert insgesamt sehr gut.

Bei der Verwendung von jQuery UI v1.11.4 hatte ich jedoch ein Problem, bei dem sich der Datepicker von der Eingabe in einem modalen Fenster (feste Positionierung) entfernt positionierte, wenn das Browserfenster nach unten verschoben wurde. Ich konnte dieses Problem durch Bearbeiten der akzeptierten Antwort wie folgt beheben:

const checkOffset = $.datepicker._checkOffset;

$.extend($.datepicker, {
  _checkOffset: function(inst, offset, isFixed) {
    if(isFixed) {
      return checkOffset.apply(this, arguments);
    } else {
      return offset;
    }
  }
});
1
sebsonic2o

So lief es für mich:

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

So positionieren Sie es, wenn die Bildschirmgröße geändert wird:

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