Comment changer la position pop-up de la commande jQuery DatePicker

Aucune idée comment faire pour obtenir le DatePicker à apparaître à la fin de la zone de texte associée au lieu d'être directement en dessous? Ce qui tend à se produire est que la zone de texte est vers le bas de la page et le DatePicker déplace jusqu'à en tenir compte et totalement couvre la zone de texte. Si l'utilisateur veut taper la date au lieu de la choisir, il ne peut pas. Je préférerais qu'il apparaisse juste après la zone de texte pour qu'il n'importe pas comment il s'ajuste verticalement.

N'importe quelle idée de comment contrôler le positionnement? Je n'ai pas vu de paramètres pour le widget, et je n'ai pas eu de chance de modifier les paramètres CSS, mais je pourrais facilement manquer quelque chose.

96
demandé sur Athafoud 2009-03-19 16:36:27

20 réponses

la réponse acceptée pour cette question n'est en fait pas pour le lecteur de données jQuery UI. Pour changer la position du lecteur de données jQuery UI, il suffit de modifier .ui-datepicker dans le fichier css. La taille du curseur de données peut également être modifiée de cette façon, il suffit d'ajuster la taille de la police.

26
répondu jonmc12 2010-05-20 19:47:42

voici ce que j'utilise:

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

Vous pouvez également ajouter un peu plus à la marge de gauche, donc ce n'est pas contre le champ de saisie.

116
répondu 2009-07-24 22:44:00

je le fais directement dans le CSS:

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

mes champs d'entrée de date sont tous de 100px large. J'ai aussi ajouté le z-index de sorte que le calendrier apparaît également au-dessus des popups AJAX.

Je ne modifie pas le fichier CSS jquery-ui; Je surcharge la classe dans mon fichier CSS principal, de sorte que je peux changer le thème ou mettre à jour le widget sans avoir à ré-entrer mes mods spécifiques.

36
répondu Christian Lescuyer 2009-08-28 12:23:39

voici ma variation de l'alignement du calendrier des utilisateurs de données.

je pense que c'est assez agréable, parce que vous pouvez contrôler le positionnement via jQuery UI Position util.

une restriction: jquery.interface.position.js requis.

Code:

$('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
répondu Rost 2017-10-04 22:49:18

Voici une autre variation qui fonctionne bien pour moi, ajuster le rect.haut + 40, rect.gauche + 0 pour répondre à vos besoins:

$(".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
répondu Patrick 2015-01-19 21:46:12

ça marche pour moi:

 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
répondu David Laberge 2014-03-07 03:06:32

tout d'abord je pense qu'il devrait y avoir une méthode afterShowing dans l'objet "datepicker", où vous pourriez changer la position après que jquery ait fait tout son vaudou dans la méthode _showDatepicker . De plus, un paramètre appelé preferedPosition serait également souhaitable, donc vous pouvez le définir et jquery le modifier au cas où la boîte de dialogue serait rendue en dehors du viewport.

il y a un" truc " pour faire cette dernière chose. Si vous étudiez les _showDatepicker la méthode, vous verrez l'utilisation d'un variable privée $.datepikcer._pos . Cette variable sera configurée si personne ne l'a configurée auparavant. Si vous modifiez cette variable avant d'afficher la boîte de dialogue, Jquery va le prendre et essayer de répartir la boîte de dialogue dans cette position, et si elle rend de l'écran, il va ajuster pour s'assurer qu'elle est visible. Ça sonne bien, hein?

problème est; _pos est privé, mais si vous ne vous en souciez pas. Vous pouvez:

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

mais attention à Jquery-ui mises à jour, parce qu'un changement dans l'implémentation interne du _showDatepicker pourrait briser votre code.

6
répondu monzonj 2011-06-29 10:47:30

j'avais besoin de positionner le curseur de données selon un div parent dans lequel résidait mon contrôle d'entrée sans frontières. Pour ce faire, j'ai utilisé l'utilitaire "position" inclus dans jQuery UI core. J'ai fait ça dans l'événement beforeShow. Comme d'autres l'ont commenté ci-dessus, vous ne pouvez pas définir la position directement dans beforeShow, car le code du cliqueur de données réinitialisera l'emplacement après avoir terminé la fonction beforeShow. Pour contourner cela, il suffit de régler la position en utilisant setInterval. Le script actuel sera complet, affichage du curseur de données, puis le code de repositionnement s'exécute immédiatement après que le curseur de données est visible. Bien que cela ne devrait jamais se produire, si le curseur de données n'est pas visible après .5 secondes, le code a une sécurité intégrée pour abandonner et effacer l'intervalle.

        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
répondu Brett Birschbach 2011-09-01 05:26:12

bind focusin après utilisation de datepicker changer css du widget du lecteur de données souhaitez l'aide

$('input.date').datepicker();
$('input.date').focusin(function(){
    $('input.date').datepicker('widget').css({left:"-=127"});
});
2
répondu anubiskong 2013-02-22 09:01:24

Je l'ai réparé avec mon code jQuery personnalisé.

  1. " a donné à mon champ d'entrée de datepicker une classe " .datepicker2 "

  2. trouver sa position actuelle depuis le haut et

  3. positionne la boîte popup, dont le nom de classe est" .ui-datepicker "

voici mon code.

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

ici " 40 " est mon pixel attendu, vous pouvez changer avec le vôtre.

2
répondu sh6210 2016-06-02 12:29:12

fix d'afficher la position du problème 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
répondu zersina 2012-06-28 08:45:55

une fonction jquery très simple.

$(".datepicker").focus(function(event){
                var dim = $(this).offset();
                $("#ui-datepicker-div").offset({
                    top     :   dim.top - 180,
                    left    :   dim.left + 150
                });
            });
1
répondu Harry 2014-08-07 01:00:28

j'ai passé un temps ridicule à essayer de comprendre ce problème pendant plusieurs pages d'un nouveau site que je développe et rien ne semblait fonctionner (y compris l'une des différentes solutions présentées ci-dessus que j'ai mis en œuvre. Je suppose que jQuery a juste changé les choses assez depuis qu'ils ont été suggérés que les solutions ne ' travailler plus. Je ne sais pas. Honnêtement, je ne comprends pas pourquoi il n'y a pas quelque chose de simple implémenté dans l'interface utilisateur de jQuery pour configurer ceci, comme il semble être un assez grand problème avec le calendrier toujours surgissant à une certaine position considérablement en bas de la page à partir de l'entrée à laquelle il est attaché.

quoi qu'il en soit, je voulais une solution finale qui était assez générique pour que je puisse l'utiliser n'importe où et ça marcherait. Il semble que j'en sois finalement arrivé à une conclusion qui évite certaines des réponses plus compliquées et spécifiques aux codes jQuery ci-dessus:

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

essentiellement, j'attache une nouvelle étiquette de style à la tête avant chaque événement" show " (supprimer la précédente, si elle est présente). Cette méthode de faire les choses tourne autour d'une grande majorité des questions que j'ai rencontré au cours du développement.

testé sur Chrome, Firefox, Safari, et IE>8 (comme IE8 ne fonctionne pas bien avec jsFiddle et je perds mon enthousiasme pour se soucier de

je sais qu'il s'agit d'un mélange de contextes jQuery et javascript, mais à ce stade Je ne veux tout simplement pas mettre l'effort de le convertir en jQuery. Ce serait simple, je sais. J'en ai tellement fini avec ça maintenant. Espérons que quelqu'un d'autre puisse bénéficier de cette solution.

1
répondu Programmer Dan 2014-12-19 16:50:43

ils ont changé le nom de la classe en ui-datepicker-trigger

donc cela fonctionne dans jquery 1.11.x

.ui-datepicker-trigger { 
margin-top:7px;
  margin-left: -30px;
  margin-bottom:0px;
  position:absolute;
  z-index:1000;
}
1
répondu Marc 2015-03-21 23:29:40

je l'ai pris de (( Comment contrôler le positionnement de jQueryUI datepicker ))

$.étendre.$(datepicker, { _checkOffset: function(inst, de décalage, de isFixed) { return compenser } });

ça marche !!!

1
répondu masoud Cheragee 2017-05-23 11:47:29

il est également intéressant de noter que si IE tombe en mode quirks, vos composants jQuery UI, et d'autres éléments, seront positionnés incorrectement.

pour vous assurer que vous ne tombez pas en mode quirks, assurez-vous de configurer votre doctype correctement à la dernière HTML5.

<!DOCTYPE html>

L'utilisation de transitional fait un gâchis de choses. Espérons que cela sauvera quelqu'un un certain temps dans le futur.

0
répondu Halfstop 2013-07-30 15:55:04

Cela met la fonctionnalité dans une méthode nommée fonction, permettant à votre code d'encapsuler ou de la méthode pour être une extension jquery. Juste utilisé sur mon code fonctionne parfaitement

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
répondu Brett Weber 2014-04-30 19:29:18

Dans Jquery.UI, il suffit de mettre à jour la fonction _checkOffset, de sorte que viewHeight soit ajouté à offset.en haut, avant de décalage est retourné.

_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
répondu David Moore 2014-07-11 09:29:50
.ui-datepicker {-ms-transform: translate(100px,100px); -webkit-transform: translate(100px,100px); transform: translate(100px,100px);}
0
répondu James 2015-01-08 16:25:26

ou vous pouvez utiliser l'événement focus sur votre objet dateSelect et l'api de position ensemble. Vous pouvez changer le haut et le bas et le gauche pour le droit ou le centre (ou vraiment tout ce que vous voulez de l'api de position). De cette façon, vous n'avez pas besoin d'un intervalle ou d'une solution incroyablement complexe et vous pouvez configurer la disposition pour répondre à vos besoins en fonction de l'endroit où l'entrée est.

dateSelect.focus(function () {
    $("#ui-datepicker-div").position({
        my: "left top",
        at: "left bottom",
        of: $(this)
    });
});
0
répondu Taugenichts 2018-10-09 19:54:25