Pergunta

O datepicker em jQueryUI processa com uma posição dinâmica. Torna acordo com o seu css se há espaço suficiente para ele, mas se não houver espaço suficiente janela tenta tornar na tela. Eu preciso dele para ficar e tornar no mesmo lugar o tempo todo, independente da posição da tela ou outras circunstâncias. Como isso pode ser feito com o datepicker jQueryUI? Outras implementações do jQuery datepicker parecem ter maneiras de fazer isso, mas eu não vejo uma maneira de fazê-lo para a versão UI.

A resposta não parece ser apenas modificando o css:

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

... desde quando o datepicker é criado dinamicamente cria superior e esquerda em grande estilo elemento. Não encontrei uma maneira de contornar isso ainda. Uma abordagem que eu vi é dar algo parecido com isso na opção beforeShow:

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

Isto tem algum efeito, mas o topo e propriedades deixadas ainda estão sendo definidas dinamicamente após este é executado quando o datepicker torna. Ainda está tentando processar na tela. Como faço para obtê-lo para tornar sempre no mesmo lugar? Meu próximo passo é, provavelmente, ir para as tripas datepicker e começar a puxar as coisas. Alguma idéia?

Note que a resposta (para a versão UI) não está em:

Foi útil?

Solução

postando isso na esperança de que ele vai ajudar os outros. Pelo menos a partir de v1.8.1 de datepicker, usando 'window.DP_jQuery.datepicker' já não funciona, porque o ponteiro (termo certo?) Agora é nomeado com um timestamp de sua criação - assim, por exemplo agora seria 'janela. DP_jQuery_1273700460448' . Então, agora, em vez de usar o ponteiro para o objeto datepicker, se referem a ele diretamente com isto:

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

Muito obrigado pela resposta abaixo para obter-me o que eu precisava.

Outras dicas

Editar: JaredC deu uma resposta atualizados para versões posteriores do jQuery acima. Switching aceito resposta para isso.

Tudo bem, isso é uma questão de monkeypatching o recurso tem de tentar tornar sempre no visor uma vez que não há nenhuma opção prevista para ativar / desativar o recurso. Felizmente é desacoplado e isolada em uma função para que possamos simplesmente entrar e substituí-lo. O código a seguir desativa completamente esse recurso só:

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

_checkOffset é chamada quando for de abertura e ele faz cálculos sobre o deslocamento e retorna um deslocamento novo se ele seria de outra maneira fora do porto vista. Isso substitui o corpo da função para apenas passar o original compensada através de direita. Então você pode usar o hack configuração beforeShow e / ou a classe .ui-datepicker css para colocá-lo onde quiser.

ligamento focusIn depois de usar datepicker mudança css de datepicker`s Widget desejo help

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

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

O problema que estava a ter é que o datepicker está posicionada de forma incorrecta dentro elementos fixos, tais como fantasia / de luz. Por alguma razão, o datepicker muda para o modo de posicionamento "fixo", quando isso acontece, e então o cálculo da compensação torna-se incorreta, quando o posicionamento absoluto teria funcionado muito bem.

No entanto, podemos obter a posição fixa correta com esse truque:

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

Em seu arquivo css, por exemplo:

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

Suas configurações importantes, sejam eles quais forem, vão substituir os padrões de linha.

no início eu tentei dar superior, esquerda em beforeShow caso de datepicker.js, que de obter substituição pelo método _showDatePicker do jQuery-UI-custom.js. Mas após o tempo limite da janela seu bom funcionamento. Abaixo está o código

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

Esta é completamente uma questão antiga no entanto Recentemente, correu para um problema semelhante a este com o jQuery UI DatePicker. Nós já estávamos usando a solução postado por @JaredC acima (especificamente este trecho de código: $.extend($.datepicker,{_checkOffset:function(inst,offset,isFixed){return offset}});). No entanto, ele não iria trabalhar para um modal que teve uma entrada em que precisávamos para tornar uma lista suspensa

Esta questão poderia ocorrer devido ao rolar para baixo a página o deslocamento da entrada nas mudanças modais relativos ao topo da página rolado. O comportamento resultante significaria que o datepicker tornaria numa posição vertical diferente dependendo de quão longe você rolou para baixo da página (nota: enquanto visível e percorrendo o datepicker já foi corrigido). A solução para este problema ( "datepicker entrada aninhados dentro de um modal") é, em vez disso calcular o posicionamento vertical da entrada em relação ao ecrã de visualização e, em seguida, adicionar a altura da entrada (permitindo a "parte superior" propriedade css do datepicker para ser direito abaixo da entrada).

O seguinte trecho é em CoffeeScript. Em vez de voltar a regulares deslocamento como por @ solução de JaredC nós em vez obter o elementId da entrada do objeto 'inst' e, em seguida, acessar o objeto via jQuery, a fim de usá-lo para calcular a distância da entrada do topo da tela em relação ao o visor.

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

A resposta aceita funciona muito bem em geral.

No entanto, usando v1.11.4 jQuery UI, eu tive um problema onde o datepicker iria posicionar-se para longe da entrada em uma janela modal (posicionamento fixo) quando a janela do navegador foi rolada para baixo. Eu era capaz de corrigir esse problema editando a resposta aceita a seguinte:

const checkOffset = $.datepicker._checkOffset;

$.extend($.datepicker, {
  _checkOffset: function(inst, offset, isFixed) {
    if(isFixed) {
      return checkOffset.apply(this, arguments);
    } else {
      return offset;
    }
  }
});
$("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>

Esta é a forma como funcionou para mim:

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

Para obtê-lo posicionado quando a tela fica redimensionada:

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

aqui é uma solução mais simples

var $picker = $( ".myspanclass" ).datepicker(); // span has display: inline-block
$picker.find('.ui-datepicker').css('margin-left', '-50px');

Por padrão o calendário do selecionador de data foi visor para o superior direito da minha caixa de entrada, de modo que o topo dele estava escondido por minha barra de menu. Aqui está como eu posicionou o widget (jquery-ui versão 1.11.4) de maneira muito simples (note que 'ui-datepicker' é o nome da classe dada pelo jquery-ui):

$(document).ready(function() {
$(".ui-datepicker").css('margin-left', '-50px', 'margin-top', '-50px');
//... 
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top