jQuery UI DatePicker para mostrar apenas o mês do ano


374

Estou usando o seletor de datas do jQuery para exibir o calendário em todo o meu aplicativo. Quero saber se posso usá-lo para exibir o mês e o ano (maio de 2010) e não o calendário?


16
Então você quer um selecionador de mês?
dotty

Você está usando o jQueryUI DatePicker?
Wpjmurray

Sim. jQueryUI DatePicker
Aanu

6
esta não é uma resposta para sua pergunta, mas a temos agora, parece muito melhor: eternicode.github.io/bootstrap-datepicker/…
Ruben

o bootstrap-datepicker parece ser um repo descontinuada, com as questões acumulando sem qualquer trabalho notável indo para corrigi-los ...
kumarharsh

Respostas:


424

Aqui está um hack (atualizado com o arquivo .html inteiro):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js"></script>
    <link rel="stylesheet" type="text/css" media="screen" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/base/jquery-ui.css">
    <script type="text/javascript">
        $(function() {
            $('.date-picker').datepicker( {
            changeMonth: true,
            changeYear: true,
            showButtonPanel: true,
            dateFormat: 'MM yy',
            onClose: function(dateText, inst) { 
                $(this).datepicker('setDate', new Date(inst.selectedYear, inst.selectedMonth, 1));
            }
            });
        });
    </script>
    <style>
    .ui-datepicker-calendar {
        display: none;
    }
    </style>
</head>
<body>
    <label for="startDate">Date :</label>
    <input name="startDate" id="startDate" class="date-picker" />
</body>
</html>

EDITAR jsfiddle para o exemplo acima: http://jsfiddle.net/DBpJe/7755/

EDIT 2 Adiciona o valor do ano do mês à caixa de entrada apenas ao clicar no botão Concluído. Também permite excluir valores da caixa de entrada, o que não é possível no campo acima http://jsfiddle.net/DBpJe/5103/

O EDIT 3 atualizou o Better Solution com base na solução de rexwolf inativa.
http://jsfiddle.net/DBpJe/5106


14
Chamar 'setDate' reabrirá o seletor em alguns navegadores. Para evitar isso, desabilitou e habilitou o seletor: $ (this) .datepicker ('disable'); $ (this) .datepicker ('setDate', nova data (ano1, mês1, 1)); $ (this) .datepicker ('ativar');
Sven Sönnichsen 30/03/11

11
@Sven aqui é uma alternativa:$(this).val($.datepicker.formatDate('MM yy', new Date(year, month, 1)));
ThiamTeck 31/03

11
Estou tentando usar esta solução, mas o uso de getDate em um datepicker retorna apenas hoje. E aí?
Supertopi

11
Vejo que muitos exemplos estão usando estilos embutidos na própria página. Isso seria um problema se, de alguma forma, você precisar de mais de um calendário (cada um com configurações diferentes, por exemplo) na mesma página. Eu prefiro adicionar estilos no arquivo .css como tal: #ui-datepicker-div.noCalendar .ui-datepicker-calendar, #ui-datepicker-div.noCalendar .ui-datepicker-header a {display: none;} #ui-datepicker-div.noCalendar .ui-datepicker-header .ui-datepicker-title{width: 100%; margin: 0;} E, em seguida, use o Javascript para manipular o comportamento:$("#ui-datepicker-div").addClass('noCalendar');
poweratom

11
No exemplo acima, se eu quiser limpar a caixa de texto, não posso. Alguém pode me ajudar.
Bik 27/02

83

Este código está funcionando perfeitamente para mim:

<script type="text/javascript">
$(document).ready(function()
{   
    $(".monthPicker").datepicker({
        dateFormat: 'MM yy',
        changeMonth: true,
        changeYear: true,
        showButtonPanel: true,

        onClose: function(dateText, inst) {
            var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
            var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
            $(this).val($.datepicker.formatDate('MM yy', new Date(year, month, 1)));
        }
    });

    $(".monthPicker").focus(function () {
        $(".ui-datepicker-calendar").hide();
        $("#ui-datepicker-div").position({
            my: "center top",
            at: "center bottom",
            of: $(this)
        });
    });
});
</script>

<label for="month">Month: </label>
<input type="text" id="month" name="month" class="monthPicker" />

A saída é:

insira a descrição da imagem aqui


Como se pode definir um valor para este calendário.
Rafik malek em

62

@ Ben Koehler , isso é prefeito! Fiz uma pequena modificação para que o uso de uma única instância do seletor de datas mais de uma vez funcione como esperado. Sem essa modificação, a data é analisada incorretamente e a data selecionada anteriormente não é destacada.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js"></script>
    <link rel="stylesheet" type="text/css" media="screen" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/base/jquery-ui.css">
    <script type="text/javascript">
    $(function() {
        $('.date-picker').datepicker( {
            changeMonth: true,
            changeYear: true,
            showButtonPanel: true,
            dateFormat: 'MM yy',
            onClose: function(dateText, inst) { 
                var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
                var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
                $(this).datepicker('setDate', new Date(year, month, 1));
            },
            beforeShow : function(input, inst) {
                var datestr;
                if ((datestr = $(this).val()).length > 0) {
                    year = datestr.substring(datestr.length-4, datestr.length);
                    month = jQuery.inArray(datestr.substring(0, datestr.length-5), $(this).datepicker('option', 'monthNamesShort'));
                    $(this).datepicker('option', 'defaultDate', new Date(year, month, 1));
                    $(this).datepicker('setDate', new Date(year, month, 1));
                }
            }
        });
    });
    </script>
    <style>
    .ui-datepicker-calendar {
        display: none;
        }
    </style>
</head>
<body>
    <label for="startDate">Date :</label>
    <input name="startDate" id="startDate" class="date-picker" />
</body>
</html>

Esta resposta está correta. No entanto, tive que alterar MM para M para obter o mês correto a ser selecionado quando uma data já estiver selecionada.
Chazaq 27/01

18

As respostas acima são muito boas. Minha única reclamação é que você não pode limpar o valor depois de definido. Também prefiro a abordagem extend-jquery-like-a-plugin.

Isso funciona perfeito para mim:

$.fn.monthYearPicker = function(options) {
    options = $.extend({
        dateFormat: "MM yy",
        changeMonth: true,
        changeYear: true,
        showButtonPanel: true,
        showAnim: ""
    }, options);
    function hideDaysFromCalendar() {
        var thisCalendar = $(this);
        $('.ui-datepicker-calendar').detach();
        // Also fix the click event on the Done button.
        $('.ui-datepicker-close').unbind("click").click(function() {
            var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
            var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
            thisCalendar.datepicker('setDate', new Date(year, month, 1));
        });
    }
    $(this).datepicker(options).focus(hideDaysFromCalendar);
}

Em seguida, invoque assim:

$('input.monthYearPicker').monthYearPicker();

2
no final, estou votando negativamente nisso porque é impraticável, pois os eventos onSelect e / ou onChangeMonthYear e / ou onClose não são acionados, ou não recebem os valores corretos ou, se substituídos, fazem o widget parar de funcionar
knocte

10
<style>
.ui-datepicker table{
    display: none;
}

<script type="text/javascript">
$(function() {
    $( "#manad" ).datepicker({
        changeMonth: true,
        changeYear: true,
        showButtonPanel: true,
        dateFormat: 'yy-mm',
        onClose: function(dateText, inst) { 
            var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
            var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
            $(this).datepicker('setDate', new Date(year, month, 1));
        },
        beforeShow : function(input, inst) {
            if ((datestr = $(this).val()).length > 0) {
                actDate = datestr.split('-');
                year = actDate[0];
                month = actDate[1]-1;
                $(this).datepicker('option', 'defaultDate', new Date(year, month));
                $(this).datepicker('setDate', new Date(year, month));
            }
        }
    });
});

Isso resolverá o problema =) Mas eu queria o timeFormat aaaa-mm

Apenas tentei no FF4


"yy" no JQuery é um ano de quatro dígitos. Se é isso que você quer, você acabou de conseguir isso.
Paweł Dyda


8

Aqui está o que eu criei. Ele oculta o calendário sem precisar de um bloco de estilo extra e adiciona um botão Limpar para lidar com o problema de não conseguir limpar o valor depois que você clica na entrada. Também funciona bem com vários seletores de mês na mesma página.

HTML:

<input type='text' class='monthpicker'>

JavaScript:

$(".monthpicker").datepicker({
    changeMonth: true,
    changeYear: true,
    dateFormat: "yy-mm",
    showButtonPanel: true,
    currentText: "This Month",
    onChangeMonthYear: function (year, month, inst) {
        $(this).val($.datepicker.formatDate('yy-mm', new Date(year, month - 1, 1)));
    },
    onClose: function(dateText, inst) {
        var month = $(".ui-datepicker-month :selected").val();
        var year = $(".ui-datepicker-year :selected").val();
        $(this).val($.datepicker.formatDate('yy-mm', new Date(year, month, 1)));
    }
}).focus(function () {
    $(".ui-datepicker-calendar").hide();
}).after(
    $("<a href='javascript: void(0);'>clear</a>").click(function() {
        $(this).prev().val('');
    })
);

5

Eu precisava de um selecionador de mês / ano para dois campos (De e até) e quando um era escolhido, o Max / Min era definido no outro ... a la picking datas das passagens aéreas. Eu estava tendo problemas para definir o máximo e o mínimo ... as datas do outro campo seriam apagadas. Graças a várias das postagens acima ... eu finalmente descobri. Você precisa definir opções e datas em uma ordem muito específica.

Veja este violino para a solução completa: Selecionador de mês / ano @ JSFiddle

Código:

var searchMinDate = "-2y";
var searchMaxDate = "-1m";
if ((new Date()).getDate() <= 5) {
    searchMaxDate = "-2m";
}
$("#txtFrom").datepicker({
    dateFormat: "M yy",
    changeMonth: true,
    changeYear: true,
    showButtonPanel: true,
    showAnim: "",
    minDate: searchMinDate,
    maxDate: searchMaxDate,
    showButtonPanel: true,
    beforeShow: function (input, inst) {
        if ((datestr = $("#txtFrom").val()).length > 0) {
            var year = datestr.substring(datestr.length - 4, datestr.length);
            var month = jQuery.inArray(datestr.substring(0, datestr.length - 5), "#txtFrom").datepicker('option', 'monthNamesShort'));
        $("#txtFrom").datepicker('option', 'defaultDate', new Date(year, month, 1));
                $("#txtFrom").datepicker('setDate', new Date(year, month, 1));
            }
        },
        onClose: function (input, inst) {
            var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
            var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
            $("#txtFrom").datepicker('option', 'defaultDate', new Date(year, month, 1));
            $("#txtFrom").datepicker('setDate', new Date(year, month, 1));
            var to = $("#txtTo").val();
            $("#txtTo").datepicker('option', 'minDate', new Date(year, month, 1));
            if (to.length > 0) {
                var toyear = to.substring(to.length - 4, to.length);
                var tomonth = jQuery.inArray(to.substring(0, to.length - 5), $("#txtTo").datepicker('option', 'monthNamesShort'));
                $("#txtTo").datepicker('option', 'defaultDate', new Date(toyear, tomonth, 1));
                $("#txtTo").datepicker('setDate', new Date(toyear, tomonth, 1));
            }
        }
    });
    $("#txtTo").datepicker({
        dateFormat: "M yy",
        changeMonth: true,
        changeYear: true,
        showButtonPanel: true,
        showAnim: "",
        minDate: searchMinDate,
        maxDate: searchMaxDate,
        showButtonPanel: true,
        beforeShow: function (input, inst) {
            if ((datestr = $("#txtTo").val()).length > 0) {
                var year = datestr.substring(datestr.length - 4, datestr.length);
                var month = jQuery.inArray(datestr.substring(0, datestr.length - 5), $("#txtTo").datepicker('option', 'monthNamesShort'));
                $("#txtTo").datepicker('option', 'defaultDate', new Date(year, month, 1));
                $("#txtTo").datepicker('setDate', new Date(year, month, 1));
            }
        },
        onClose: function (input, inst) {
            var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
            var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
            $("#txtTo").datepicker('option', 'defaultDate', new Date(year, month, 1));
            $("#txtTo").datepicker('setDate', new Date(year, month, 1));
            var from = $("#txtFrom").val();
            $("#txtFrom").datepicker('option', 'maxDate', new Date(year, month, 1));
            if (from.length > 0) {
                var fryear = from.substring(from.length - 4, from.length);
                var frmonth = jQuery.inArray(from.substring(0, from.length - 5), $("#txtFrom").datepicker('option', 'monthNamesShort'));
                $("#txtFrom").datepicker('option', 'defaultDate', new Date(fryear, frmonth, 1));
                $("#txtFrom").datepicker('setDate', new Date(fryear, frmonth, 1));
            }

        }
    });

Adicione isso também a um bloco de estilos, como mencionado acima:

.ui-datepicker-calendar { display: none !important; }

5

Combinei muitas das boas respostas acima e cheguei a isso:

    $('#payCardExpireDate').datepicker(
            {
                dateFormat: "mm/yy",
                changeMonth: true,
                changeYear: true,
                showButtonPanel: true,
                onClose: function(dateText, inst) { 
                    var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
                    var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
                    $(this).datepicker('setDate', new Date(year, month, 1)).trigger('change');
                },
                beforeShow : function(input, inst) {
                    if ((datestr = $(this).val()).length > 0) {
                        year = datestr.substring(datestr.length-4, datestr.length);
                        month = datestr.substring(0, 2);
                        $(this).datepicker('option', 'defaultDate', new Date(year, month-1, 1));
                        $(this).datepicker('setDate', new Date(year, month-1, 1));
                    }
                }
            }).focus(function () {
                $(".ui-datepicker-calendar").hide();
                $("#ui-datepicker-div").position({
                    my: "center top",
                    at: "center bottom",
                    of: $(this)
                });
            });

Está provado que funciona, mas enfrentando muitos erros, então fui forçado a corrigir em vários locais do datepicker:

if($.datepicker._get(inst, "dateFormat") === "mm/yy")
{
    $(".ui-datepicker-calendar").hide();
}

patch1: em _showDatepicker: para suavizar a ocultação;

patch2: em _checkOffset: para corrigir o posicionamento do selecionador de mês (caso contrário, quando o campo estiver na parte inferior do navegador, a verificação de deslocamento estará desativada);

patch3: em onClose de _hideDatepicker: caso contrário, ao fechar os campos da data, piscará por um período muito curto, o que é muito irritante.

Eu sei que minha correção estava longe de ser boa, mas por enquanto está funcionando. Espero que ajude.


Basta adicionar esta linha ao beforeShow: {inst.dpDiv.addClass ('month_year_datepicker')}. as datas piscando pararão :). Também acho que .focus não vai ser necessário, em seguida
Parag

5

Adicione mais uma solução simples

 $(function() {
    $('.monthYearPicker').datepicker({
        changeMonth: true,
        changeYear: true,
        showButtonPanel: true,
        dateFormat: 'M yy'
    }).focus(function() {
        var thisCalendar = $(this);
        $('.ui-datepicker-calendar').detach();
        $('.ui-datepicker-close').click(function() {
var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
thisCalendar.datepicker('setDate', new Date(year, month, 1));
        });
    });
});

http://jsfiddle.net/tmnasim/JLydp/
Recursos :

  • exibir apenas mês / ano
  • Adiciona o valor do ano do mês à caixa de entrada apenas ao clicar no botão Concluído
  • Nenhum comportamento de "reabrir" ao clicar em "Concluído"
    ------------------------------------
    outra solução que funcione bem para datepicker e monthpicker na mesma página: (também evite o erro de clicar várias vezes no botão anterior no IE, isso pode ocorrer se usarmos a função focus)
    JS fiddle link

4

Sou eu ou isso não está funcionando como deveria no IE (8)? A data muda quando o clique é concluído, mas o datepicker se abre novamente, até você clicar em algum lugar da página para perder o foco no campo de entrada ...

Estou procurando resolver isso.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js"></script>
    <link rel="stylesheet" type="text/css" media="screen" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/base/jquery-ui.css">
<script type="text/javascript">
$(function() {
    $('.date-picker').datepicker( {
        changeMonth: true,
        changeYear: true,
        showButtonPanel: true,
        dateFormat: 'MM yy',
        onClose: function(dateText, inst) { 
            var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
            var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
            $(this).datepicker('setDate', new Date(year, month, 1));
        }
    });
});
</script>
<style>
.ui-datepicker-calendar {
    display: none;
    }
</style>
</head>
<body>
    <label for="startDate">Date :</label>
    <input name="startDate" id="startDate" class="date-picker" />
</body>
</html>

11
$ (this) .datepicker ('desativar'); $ (this) .datepicker ('setDate', nova data (ano, mês, 1)); $ (this) .datepicker ('ativar'); Resolve o problema.
Tom Van Schoor

11
Esta não é uma resposta
sisharp

4

Se você estiver procurando por um selecionador de mês, tente este jquery.mtz.monthpicker

Isso funcionou bem para mim.

options = {
    pattern: 'yyyy-mm', // Default is 'mm/yyyy' and separator char is not mandatory
    selectedYear: 2010,
    startYear: 2008,
    finalYear: 2012,
    monthNames: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
};

$('#custom_widget').monthpicker(options);

Link está morto. Este site não pode ser acessado | Não foi possível encontrar o endereço DNS do servidor lucianocosta.info.
Pang

11
Aqui está um link atualizado: lucianocosta.com.br/jquery.mtz.monthpicker
Sebastian S.

O link atualizado também está quebrado.
nasch

4

Como muitos outros, eu encontrei vários problemas ao tentar fazer isso, e apenas uma combinação das soluções postadas e, eventualmente, um grande truque para torná-lo perfeito, me trouxe uma solução.

Problemas com outras soluções neste segmento que eu tentei:

  1. A seleção de uma nova data em um selecionador de datas também alteraria a data (interna) de outros seletores de datas; portanto, quando você abrisse os outros novamente (ou tentasse obter a data deles), eles teriam uma data diferente da exibida na entrada atribuída. -campo.
  2. O marcador de data não "lembraria" a data quando aberto novamente.
  3. O código para manipular as datas usava substring para não ser compatível com todos os formatos.
  4. "My monthpicker" mudou apenas o campo de entrada ao fechá-lo, e não sempre que os valores foram alterados.
  5. O campo de entrada não é atualizado corretamente, se você digitar uma string de entrada formatada incorretamente para uma data e, em seguida, clique em 'Fechar' no selecionador de datas.
  6. Não posso ter seletores de datas normais, que mostram os dias, na mesma página que os seletores de mês, que não mostram os dias.

Finalmente encontrei uma maneira de corrigir todos esses problemas . Os quatro primeiros podem ser corrigidos simplesmente tomando cuidado com a forma como você faz referência aos seus selecionadores de data e mês no código interno e, é claro, fazendo algumas atualizações manuais dos seus selecionadores. Isso você pode ver nos exemplos de instanciação na parte inferior. O quinto problema pode ser ajudado adicionando algum código personalizado às funções do datepicker.

NOTA: NÃO é necessário usar os seguintes scripts do monthpicker para corrigir os três primeiros problemas no datepicker normal. Basta usar o script de instanciação datepicker na parte inferior desta postagem.

Agora, para usar os seletores de mês e corrigir o último problema, precisamos separar os seletores de data e os seletores de mês. Poderíamos ter um dos poucos complementos de mês do picador de jQuery-UI por aí, mas alguns não têm flexibilidade / capacidade de localização, outros não têm suporte para animação ... então, o que fazer? Role o seu "próprio" a partir do código datepicker! Com isso, você obtém um medidor de meses em pleno funcionamento, com todas as funcionalidades do medidor de data, apenas sem a exibição de dias.

Forneci um js-script do monthpicker e o script CSS que o acompanha , usando o método descrito abaixo, com o código jQuery-UI v1.11.1. Simplesmente copie esses trechos de código para dois novos arquivos, monthpicker.js e monthpicker.css, respectivamente.

Se você quiser ler sobre o processo bastante simples pelo qual converti o datepicker em um monthpicker, role para baixo até a última seção.


Agora, adicione os seletores de data e mês à página!

Os seguintes trechos de código javascript funcionam com vários seletores de datas e / ou seletores de mês na página, sem os problemas acima mencionados! Corrigido geralmente usando '$ (this).' muito :)

O primeiro script é para um seletor de datas normal e o segundo é para os "novos" seletores de mês.

O .after comentado , que permite criar algum elemento para limpar o campo de entrada, é roubado da resposta de Paul Richards.

Estou usando o formato "MM yy" no meu monthpicker e o formato 'aa-mm-dd' no meu datepicker, mas isso é totalmente compatível com todos os formatos , portanto, você pode usar o que quiser. Simplesmente altere a opção 'dateFormat'. As opções padrão 'showButtonPanel', 'showAnim' e 'yearRange' são obviamente opcionais e personalizáveis ​​para seus desejos.


Adicionando um datepicker

Instanciação do datepicker. Este vai de 90 anos atrás e até os dias atuais. Ele ajuda a manter o campo de entrada correto, especialmente se você definir as opções defaultDate, minDate e maxDate, mas poderá lidar com isso se não o fizer. Ele funcionará com qualquer dateFormat que você escolher.

        $('#MyDateTextBox').datepicker({
            dateFormat: 'yy-mm-dd',
            changeMonth: true,
            changeYear: true,
            showButtonPanel: true,
            showMonthAfterYear: true,
            showWeek: true,
            showAnim: "drop",
            constrainInput: true,
            yearRange: "-90:",
            minDate: new Date((new Date().getFullYear() - 90), new Date().getMonth(), new Date().getDate()),
            maxDate: new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate()),
            defaultDate: new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate()),

            onClose: function (dateText, inst) {
                // When onClose is called after we have clicked a day (and not clicked 'Close' or outside the datepicker), the input-field is automatically
                // updated with a valid date-string. They will always pass, because minDate and maxDate are already enforced by the datepicker UI.
                // This try is to catch and handle the situations, where you open the datepicker, and manually type in an invalid date in the field,
                // and then close the datepicker by clicking outside the datepicker, or click 'Close', in which case no validation takes place.
                try {
                    // If datepicker can parse the date using our formatstring, the instance will automatically parse
                    // and apply it for us (after the onClose is done).
                    // If the input-string is invalid, 'parseDate' will throw an exception, and go to our catch.
                    // If the input-string is EMPTY, then 'parseDate' will NOT throw an exception, but simply return null!
                    var typedDate = $.datepicker.parseDate($(this).datepicker('option', 'dateFormat'), $(this).val());

                    // typedDate will be null if the entered string is empty. Throwing an exception will force the datepicker to
                    // reset to the last set default date.
                    // You may want to just leave the input-field empty, in which case you should replace 'throw "No date selected";' with 'return;'
                    if (typedDate == null)throw "No date selected";

                    // We do a manual check to see if the date is within minDate and maxDate, if they are defined.
                    // If all goes well, the default date is set to the new date, and datepicker will apply the date for us.
                    var minDate = $(this).datepicker("option", "minDate");
                    var maxDate = $(this).datepicker("option", "maxDate");
                    if (minDate !== null && typedDate < minDate) throw "Date is lower than minDate!";
                    if (maxDate !== null && typedDate > maxDate) throw "Date is higher than maxDate!";

                    // We update the default date, because the date seems valid.
                    // We do not need to manually update the input-field, as datepicker has already done this automatically.
                    $(this).datepicker('option', 'defaultDate', typedDate);
                }
                catch (err) {
                    console.log("onClose: " + err);
                    // Standard behavior is that datepicker does nothing to fix the value of the input field, until you choose
                    // a new valid date, by clicking on a day.
                    // Instead, we set the current date, as well as the value of the input-field, to the last selected (and
                    // accepted/validated) date from the datepicker, by getting its default date. This only works, because
                    // we manually change the default date of the datepicker whenever a new date is selected, in both 'beforeShow'
                    // and 'onClose'.
                    var date = $(this).datepicker('option', 'defaultDate');
                    $(this).val($.datepicker.formatDate($(this).datepicker('option', 'dateFormat'), date));
                    $(this).datepicker('setDate', date);
                }
            },

            beforeShow: function (input, inst) {
                // beforeShow is particularly irritating when initializing the input-field with a date-string.
                // The date-string will be parsed, and used to set the currently selected date in the datepicker.
                // BUT, if it is outside the scope of the minDate and maxDate, the text in the input-field is not
                // automatically updated, only the internal selected date, until you choose a new date (or, because
                // of our onClose function, whenever you click close or click outside the datepicker).
                // We want the input-field to always show the date that is currently chosen in our datepicker,
                // so we do some checks to see if it needs updating. This may not catch ALL cases, but these are
                // the primary ones: invalid date-format; date is too early; date is too late.
                try {
                    // If datepicker can parse the date using our formatstring, the instance will automatically parse
                    // and apply it for us (after the onClose is done).
                    // If the input-string is invalid, 'parseDate' will throw an exception, and go to our catch.
                    // If the input-string is EMPTY, then 'parseDate' will NOT throw an exception, but simply return null!
                    var typedDate = $.datepicker.parseDate($(this).datepicker('option', 'dateFormat'), $(this).val());

                    // typedDate will be null if the entered string is empty. Throwing an exception will force the datepicker to
                    // reset to the last set default date.
                    // You may want to just leave the input-field empty, in which case you should replace 'throw "No date selected";' with 'return;'
                    if (typedDate == null)throw "No date selected";

                    // We do a manual check to see if the date is within minDate and maxDate, if they are defined.
                    // If all goes well, the default date is set to the new date, and datepicker will apply the date for us.
                    var minDate = $(this).datepicker("option", "minDate");
                    var maxDate = $(this).datepicker("option", "maxDate");
                    if (minDate !== null && typedDate < minDate) throw "Date is lower than minDate!";
                    if (maxDate !== null && typedDate > maxDate) throw "Date is higher than maxDate!";

                    // We update the input-field, and the default date, because the date seems valid.
                    // We also manually update the input-field, as datepicker does not automatically do this when opened.
                    $(this).val($.datepicker.formatDate($(this).datepicker('option', 'dateFormat'), typedDate));
                    $(this).datepicker('option', 'defaultDate', typedDate);
                }
                catch (err) {
                    // Standard behavior is that datepicker does nothing to fix the value of the input field, until you choose
                    // a new valid date, by clicking on a day.
                    // We want the same behavior when opening the datepicker, so we set the current date, as well as the value
                    // of the input-field, to the last selected (and accepted/validated) date from the datepicker, by getting
                    // its default date. This only works, because we manually change the default date of the datepicker whenever
                    // a new date is selected, in both 'beforeShow' and 'onClose', AND have a default date set in the datepicker options.
                    var date = $(this).datepicker('option', 'defaultDate');
                    $(this).val($.datepicker.formatDate($(this).datepicker('option', 'dateFormat'), date));
                    $(this).datepicker('setDate', date);
                }
            }
        })
    //.after( // this makes a link labeled "clear" appear to the right of the input-field, which clears the text in it
    //    $("<a href='javascript: void(0);'>clear</a>").click(function() {
    //        $(this).prev().val('');
    //    })
    //)
    ;

Adicionando um monthpicker

Inclua o arquivo monthpicker.js e o arquivo monthpicker.css na página que você deseja usar.

Instanciação do monthpicker O valor recuperado deste monthpicker, é sempre o PRIMEIRO dia do mês selecionado. Começa no mês atual e varia de 100 anos atrás e 10 anos no futuro.

    $('#MyMonthTextBox').monthpicker({
        dateFormat: 'MM yy',
        changeMonth: true,
        changeYear: true,
        showMonthAfterYear: true,
        showAnim: "drop",
        constrainInput: true,
        yearRange: "-100Y:+10Y",
        minDate: new Date(new Date().getFullYear() - 100, new Date().getMonth(), 1),
        maxDate: new Date((new Date().getFullYear() + 10), new Date().getMonth(), 1),
        defaultDate: new Date(new Date().getFullYear(), new Date().getMonth(), 1),

        // Monthpicker functions
        onClose: function (dateText, inst) {
            var date = new Date(inst.selectedYear, inst.selectedMonth, 1);
            $(this).monthpicker('option', 'defaultDate', date);
            $(this).monthpicker('setDate', date);
        },

        beforeShow: function (input, inst) {
            if ($(this).monthpicker("getDate") !== null) {
                // Making sure that the date set is the first of the month.
                if($(this).monthpicker("getDate").getDate() !== 1){
                    var date = new Date(inst.selectedYear, inst.selectedMonth, 1);
                    $(this).monthpicker('option', 'defaultDate', date);
                    $(this).monthpicker('setDate', date);
                }
            } else {
                // If the date is null, we reset it to the defaultDate. Make sure that the defaultDate is always set to the first of the month!
                $(this).monthpicker('setDate', $(this).monthpicker('option', 'defaultDate'));
            }
        },
        // Special monthpicker function!
        onChangeMonthYear: function (year, month, inst) {
            $(this).val($.monthpicker.formatDate($(this).monthpicker('option', 'dateFormat'), new Date(year, month - 1, 1)));
        }
    })
    //.after( // this makes a link labeled "clear" appear to the right of the input-field, which clears the text in it
    //    $("<a href='javascript: void(0);'>clear</a>").click(function() {
    //        $(this).prev().val('');
    //    })
    //)
    ;

É isso aí! É tudo o que você precisa para fazer uma escolha mensal.

Parece que não consigo fazer com que o jsfiddle funcione com isso, mas está funcionando para mim no meu projeto asp.net MVC. Faça o que você normalmente faz para adicionar um datepicker à sua página e incorpore os scripts acima, possivelmente alterando o seletor (que significa $ ("# MyMonthTextBox")) para algo que funcione para você.

Espero que isso ajude alguém.

Links para pastebins para algumas configurações extras de data e mês:

  1. Monthpicker trabalhando no último dia do mês . A data que você obtém deste mês é sempre o último dia do mês.

  2. Dois coletores mensais colaboradores ; 'start' está funcionando no primeiro dia do mês e 'end' está funcionando no último dia do mês. Ambos são restritos um pelo outro, portanto, a escolha de um mês no 'final' anterior ao mês selecionado no 'início' mudará 'início' para o mesmo mês que 'final'. E vice versa. OPCIONAL: Ao selecionar um mês em 'start', a 'minDate' em 'end' é definida para esse mês. Para remover esse recurso, comente uma linha em onClose (leia os comentários).

  3. Dois coletores de datas colaboradores ; Ambos são restritos um pelo outro, portanto, escolher uma data no 'final' anterior à data selecionada no 'início' mudará 'início' para o mesmo mês que 'final'. E vice versa. OPCIONAL: Ao selecionar uma data em 'início', o 'minDate' em 'final' é definido para essa data. Para remover esse recurso, comente uma linha em onClose (leia os comentários).


Como mudei o DatePicker para um MonthPicker

Peguei todo o código javascript do jquery-ui-1.11.1.js referente ao datepicker, colei-o em um novo arquivo js e substitui as seguintes strings:

  • "datepicker" ==> "monthpicker"
  • "Datepicker" ==> "Monthpicker"
  • "selecionador de data" ==> "selecionador de mês"
  • "Selecionador de data" ==> "Selecionador de mês"

Em seguida, removi a parte do loop for, que cria toda a div ui-datepicker-calendar (a div que outras soluções ocultam usando CSS). Isso pode ser encontrado na função _generateHTML: (inst).

Encontre a linha que diz:

"</div><table class='ui-datepicker-calendar'><thead>" +

Marque tudo, desde o div-tag de fechamento e até (e não incluindo) a linha onde está escrito:

drawMonth++;

Agora vai ser infeliz porque precisamos fechar algumas coisas. Após o fechamento da tag div de antes, adicione este:

";

O código agora deve ser bem costurado. Aqui está um trecho de código mostrando o que você deveria ter acabado:

...other code...

calender += "<div class='ui-monthpicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
                (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
                (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
                this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
                    row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
                "</div>";
            drawMonth++;
            if (drawMonth > 11) {
                drawMonth = 0;
                drawYear++;
            }

...other code...

Em seguida, copiei / colei o código do jquery-ui.css pertencente aos datepickers para um novo arquivo CSS e substitui as seguintes strings:

  • "datepicker" ==> "monthpicker"

3

depois de procurar no jQueryUI.com o datepicker, eis a minha conclusão e a resposta à sua pergunta.

Primeiro, eu diria não à sua pergunta. Você não pode usar o dateQuicker do jQueryUI para escolher apenas o mês e o ano. Não é suportado. Não possui função de retorno de chamada para isso.

Mas você pode cortá-lo para exibir apenas mês e ano usando css para ocultar os dias etc. E acho que ainda não fará sentido, pois você precisa clicar nas datas para escolher uma data.

Posso dizer que você só precisa usar outro seletor de datas. Como o que Roger sugeriu.


3

Eu tive o problema de selecionador de data misturado com selecionador de mês. Eu resolvi assim.

    $('.monthpicker').focus(function()
    {
    $(".ui-datepicker-calendar").show();
    }).datepicker( {
        changeMonth: true,
        changeYear: true,
        showButtonPanel: true,
        dateFormat: 'MM/yy',
        create: function (input, inst) { 

         },
        onClose: function(dateText, inst) { 
            var month = 1+parseInt($("#ui-datepicker-div .ui-datepicker-month :selected").val());           
            var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();

        }
    });

3

Se alguém quiser isso também para vários calendários, não é muito difícil adicionar essa funcionalidade ao jquery ui. com pesquisa minificada por:

x+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+t+'">'+(/all|left/.test(t)&&C==0?c?f:n:"")+(

adicione isso na frente de x

var accl = ''; if(this._get(a,"justMonth")) {accl = ' ui-datepicker-just_month';}

procurar por

<table class="ui-datepicker-calendar

e substitua-o por

<table class="ui-datepicker-calendar'+accl+'

também procure

this._defaults={

substitua-o por

this._defaults={justMonth:false,

para css, você deve usar:

.ui-datepicker table.ui-datepicker-just_month{
    display: none;
}

Depois que tudo estiver pronto, basta acessar as funções init do datepicker e fornecer a configuração var

$('#txt_month_chart_view').datepicker({
    changeMonth: true,
        changeYear: true,
        showButtonPanel: true,
        dateFormat: 'MM yy',
        justMonth: true,
        create: function(input, inst) {
            $(".ui-datepicker table").addClass("badbad");
        },
        onClose: function(dateText, inst) {
            var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
            var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
            $(this).datepicker('setDate', new Date(year, month, 1));
        }
});

justMonth: true é a chave aqui :)



2

Fiz alguns refinamentos na resposta quase perfeita do BrianS acima:

  1. Regexei o valor definido no programa porque acho que, na verdade, o torna um pouco mais legível nesse caso (embora note que estou usando um formato um pouco diferente)

  2. Meu cliente não queria calendário, então adicionei uma adição de classe em mostrar / ocultar para fazer isso sem afetar nenhum outro selecionador de datas. A remoção da classe está em um cronômetro para evitar que a tabela volte a piscar à medida que o contador de datas desaparece, o que parece ser muito perceptível no IE.

EDIT: Um problema que ainda não foi resolvido é que não há como esvaziar o selecionador de datas - limpe o campo e clique fora e ele repovoa com a data selecionada.

EDIT2: Eu não consegui resolver isso muito bem (ou seja, sem adicionar um botão Limpar separado ao lado da entrada), então acabei usando isso: https://github.com/thebrowser/jquery.ui.monthpicker - se alguém puder obtenha a interface do usuário padrão que seria incrível.

    $('.typeof__monthpicker').datepicker({
        dateFormat: 'mm/yy',
        showButtonPanel:true,
        beforeShow: 
            function(input, dpicker)
            {                           
                if(/^(\d\d)\/(\d\d\d\d)$/.exec($(this).val()))
                {
                    var d = new Date(RegExp.$2, parseInt(RegExp.$1, 10) - 1, 1);

                    $(this).datepicker('option', 'defaultDate', d);
                    $(this).datepicker('setDate', d);
                }

                $('#ui-datepicker-div').addClass('month_only');
            },
        onClose: 
            function(dt, dpicker)
            {
                setTimeout(function() { $('#ui-datepicker-div').removeClass('month_only') }, 250);

                var m = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
                var y = $("#ui-datepicker-div .ui-datepicker-year :selected").val();

                $(this).datepicker('setDate', new Date(y, m, 1));
            }
    });

Você também precisa desta regra de estilo:

#ui-datepicker-div.month_only .ui-datepicker-calendar {
display:none
}

2

Gostei da resposta @ user1857829 e de sua abordagem "estender-jquery como um plug-in". Acabei de fazer uma pequena modificação para que, quando você mude de mês ou ano, o selecionador realmente anote a data no campo. Descobri que gostaria desse comportamento depois de usá-lo um pouco.

jQuery.fn.monthYearPicker = function(options) {
  options = $.extend({
    dateFormat: "mm/yy",
    changeMonth: true,
    changeYear: true,
    showButtonPanel: true,
    showAnim: "",
    onChangeMonthYear: writeSelectedDate
  }, options);
  function writeSelectedDate(year, month, inst ){
   var thisFormat = jQuery(this).datepicker("option", "dateFormat");
   var d = jQuery.datepicker.formatDate(thisFormat, new Date(year, month-1, 1));
   inst.input.val(d);
  }
  function hideDaysFromCalendar() {
    var thisCalendar = $(this);
    jQuery('.ui-datepicker-calendar').detach();
    // Also fix the click event on the Done button.
    jQuery('.ui-datepicker-close').unbind("click").click(function() {
      var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
      var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
      thisCalendar.datepicker('setDate', new Date(year, month, 1));
      thisCalendar.datepicker("hide");
    });
  }
  jQuery(this).datepicker(options).focus(hideDaysFromCalendar);
}

2

Eu tive algumas dificuldades com a resposta aceita e ninguém mais poderia ser usado com um esforço mínimo como base. Então, decidi ajustar a versão mais recente da resposta aceita até que ela satisfaz pelo menos os padrões mínimos de codificação / reutilização de JS.

Aqui está uma solução muito mais limpa que a 3ª (mais recente) edição da resposta aceita por Ben Koehler . Além disso, irá:

  • trabalhe não apenas com o mm/yyformato, mas com qualquer outro, incluindo os OPs MM yy.
  • não oculte o calendário de outros seletores de datas na página.
  • não poluir implicitamente o objeto global JS com o datestr, month, yearetc variáveis.

Confira:

$('.date-picker').datepicker({
    dateFormat: 'MM yy',
    changeMonth: true,
    changeYear: true,
    showButtonPanel: true,
    onClose: function (dateText, inst) {
        var isDonePressed = inst.dpDiv.find('.ui-datepicker-close').hasClass('ui-state-hover');
        if (!isDonePressed)
            return;

        var month = inst.dpDiv.find('.ui-datepicker-month').find(':selected').val(),
            year = inst.dpDiv.find('.ui-datepicker-year').find(':selected').val();

        $(this).datepicker('setDate', new Date(year, month, 1)).change();
        $('.date-picker').focusout();
    },
    beforeShow: function (input, inst) {
        var $this = $(this),
            // For the simplicity we suppose the dateFormat will be always without the day part, so we
            // manually add it since the $.datepicker.parseDate will throw if the date string doesn't contain the day part
            dateFormat = 'd ' + $this.datepicker('option', 'dateFormat'),
            date;

        try {
            date = $.datepicker.parseDate(dateFormat, '1 ' + $this.val());
        } catch (ex) {
            return;
        }

        $this.datepicker('option', 'defaultDate', date);
        $this.datepicker('setDate', date);

        inst.dpDiv.addClass('datepicker-month-year');
    }
});

E tudo o mais que você precisa é o seguinte CSS em algum lugar:

.datepicker-month-year .ui-datepicker-calendar {
    display: none;
}

É isso aí. Espero que o exposto economize algum tempo para outros leitores.


11
Just and FYI. A linha 'inst.dpDiv.addClass (' datepicker-month-year ');' adicionará o mês inteiro ao div do calendário do datepicker, o que significa que, se houver outros campos de data com o datepicker, eles deixarão de funcionar por causa disso. Como existe apenas uma única div para o calendário, seria interessante adicionar um '$ ('. Datepicker-month-year '). RemoveClass (' datepicker-month-year ');' usando o beforeShow em quaisquer outros seletores de data que exijam o calendário tradicional. OU, remova a turma quando você perder o foco. Mas não consegui encontrar nada relacionado a isso na API
Johnny Bigoode 29/11/16

11
Esta é a resposta completa que todos devem usar. O maior problema resolvido para mim foi o pop-up de entrada de data sempre com o mês e o ano atuais, independentemente do que já está nele. Essa resposta foi corrigida.
Alex F

1

Sei que é uma resposta um pouco tardia, mas tive o mesmo problema alguns dias antes e vim com uma solução agradável e suave. Primeiro eu encontrei esse ótimo selecionador de datas aqui

Acabei de atualizar a classe CSS (jquery.calendarPicker.css) que vem com o exemplo desta forma:

.calMonth {
  /*border-bottom: 1px dashed #666;
  padding-bottom: 5px;
  margin-bottom: 5px;*/
}

.calDay 
{
    display:none;
}

O plug-in dispara um evento DateChanged quando você altera alguma coisa, por isso não importa que você não esteja clicando em um dia (e se encaixa como um selecionador de ano e mês)

Espero que ajude!



1

Tentei as várias soluções fornecidas aqui e elas funcionaram bem se você simplesmente quisesse algumas suspensões.

O melhor (na aparência, etc.) 'selecionador' ( https://github.com/thebrowser/jquery.ui.monthpicker ) sugerido aqui é basicamente uma cópia de uma versão antiga do jquery-ui datepicker com o _generateHTML reescrito. No entanto, achei que ele não funciona mais bem com o jquery-ui atual (1.10.2) e tinha outros problemas (não fecha em esc, não fecha em outra abertura de widget, tem estilos codificados).

Em vez de tentar corrigir o seletor de mês e tentar novamente o mesmo processo com o seletor de datas mais recente, fui conectando-me às partes relevantes do seletor de datas existente.

Isso envolve a substituição:

  • _generateHTML (para criar a marcação do selecionador de mês)
  • parseDate (como não gosta quando não há componente diurno),
  • _selectDay (como o datepicker usa .html () para obter o valor do dia)

Como essa pergunta é um pouco antiga e já está bem respondida, aqui está apenas a substituição _selectDay para mostrar como isso foi feito:

jQuery.datepicker._base_parseDate = jQuery.datepicker._base_parseDate || jQuery.datepicker.parseDate;
jQuery.datepicker.parseDate = function (format, value, settings) {
    if (format != "M y") return jQuery.datepicker._hvnbase_parseDate(format, value, settings);
    // "M y" on parse gives error as doesn't have a day value, so 'hack' it by simply adding a day component
    return jQuery.datepicker._hvnbase_parseDate("d " + format, "1 " + value, settings);
};

Como afirmado, esta é uma pergunta antiga, mas achei útil, pois queria adicionar feedback com uma solução alterante.


0

para um monthpicker, usando JQuery v 1.7.2, eu tenho o seguinte javascript que está fazendo exatamente isso

$l("[id$=txtDtPicker]").monthpicker({
showOn: "both",
buttonImage: "../../images/Calendar.png",
buttonImageOnly: true,
pattern: 'yyyymm', // Default is 'mm/yyyy' and separator char is not mandatory
monthNames: ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez']
});


0

Obrigado pela solução de Ben Koehler.

No entanto, tive um problema com várias instâncias de selecionadores de datas, com algumas delas necessárias na seleção do dia. A solução de Ben Koehler (na edição 3) funciona, mas oculta a seleção do dia em todas as instâncias. Aqui está uma atualização que resolve esse problema:

$('.date-picker').datepicker({
    dateFormat: "mm/yy",
    changeMonth: true,
    changeYear: true,
    showButtonPanel: true,
    onClose: function(dateText, inst) {
        if($('#ui-datepicker-div').html().indexOf('ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all ui-state-hover') > -1) {
            $(this).datepicker(
                'setDate',
                new Date(
                    $("#ui-datepicker-div .ui-datepicker-year :selected").val(),
                    $("#ui-datepicker-div .ui-datepicker-month :selected").val(),
                    1
                )
            ).trigger('change');
            $('.date-picker').focusout();
        }
        $("#ui-datepicker-div").removeClass("month_year_datepicker");
    },
    beforeShow : function(input, inst) {
        if((datestr = $(this).val()).length > 0) {
            year = datestr.substring(datestr.length-4, datestr.length);
            month = datestr.substring(0, 2);
            $(this).datepicker('option', 'defaultDate', new Date(year, month-1, 1));
            $(this).datepicker('setDate', new Date(year, month-1, 1));
            $("#ui-datepicker-div").addClass("month_year_datepicker");
        }
    }
});

-2

Use a onSelectchamada de volta e remova a parte do ano manualmente e defina o texto no campo manualmente


3
Eu acho que você não está lendo a pergunta. Aanu deseja "exibir o mês e o ano (maio de 2010) e não o calendário".
Reigel
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.