web-dev-qa-db-fra.com

jQuery UI DatePicker pour afficher le mois, l'année seulement

J'utilise le sélecteur de date jQuery pour afficher le calendrier sur l'ensemble de mon application. Je souhaite savoir si je peux l'utiliser pour afficher le mois et l'année (mai 2010) et non le calendrier.

363
Aanu

Voici un hack (mis à jour avec le fichier entier .html):

<!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>

EDIT jsfiddle pour l'exemple ci-dessus: http://jsfiddle.net/DBpJe/7755/

EDIT 2 Ajoute la valeur mois année à la zone de saisie uniquement en cliquant sur le bouton Terminé. Permet également de supprimer les valeurs de la zone de saisie, ce qui n'est pas possible dans le champ ci-dessus http://jsfiddle.net/DBpJe/5103/

EDIT 3 a mis à jour Better Solution en fonction de la solution de rexwolf vers le bas.
http://jsfiddle.net/DBpJe/5106

414
Ben Koehler

Ce code fonctionne parfaitement pour moi:

<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" />

La sortie est:

enter image description here

79

@ Ben Koehler , c'est le préfet! J'ai apporté une modification mineure afin que l'utilisation d'une seule instance du sélecteur de date plusieurs fois fonctionne comme prévu. Sans cette modification, la date n'est pas analysée correctement et la date précédemment sélectionnée n'est pas mise en surbrillance.

<!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>
61
BrianS

Les réponses ci-dessus sont très bonnes. Mon seul reproche est que vous ne pouvez pas effacer la valeur une fois qu'elle a été définie. De plus, je préfère l'approche extend-jquery-like-a-plugin.

Cela fonctionne parfaitement pour moi:

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

Puis invoquez comme ceci:

$('input.monthYearPicker').monthYearPicker();
17
user1857829
<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));
            }
        }
    });
});

Cela résoudra le problème =) Mais je voulais le timeFormat yyyy-mm

Seulement essayé dans FF4 cependant

10
Erik Polder

J'ai eu ce même besoin aujourd'hui et l'ai trouvé sur github, fonctionne avec jQueryUI et a sélecteur de mois au lieu de jours dans le calendrier

https://github.com/thebrowser/jquery.ui.monthpicker

9
Anthony Shaw

Voici ce que je suis venu avec. Il masque le calendrier sans avoir besoin d'un bloc de style supplémentaire et ajoute un bouton permettant de résoudre le problème de l'impossibilité d'effacer la valeur une fois que vous avez cliqué sur l'entrée. Fonctionne également bien avec plusieurs mois sur la même page.

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('');
    })
);
8
Paul Richards

Ajouter une solution simple supplémentaire

 $(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/
Caractéristiques :

  • afficher uniquement mois/année
  • Ajoute la valeur mois année à la zone de saisie uniquement en cliquant sur le bouton Terminé
  • Pas de comportement "rouvrir" lorsque vous cliquez sur "Terminé"
    ----------------------------------------
    une autre solution qui fonctionne bien pour datepicker et monthpicker dans la même page: (évitez également le bug de clic multiple sur le bouton précédent dans IE, cela peut arriver si nous utilisons la fonction focus)
    lien de violon JS
5
Chinh Phan

J'ai combiné plusieurs des bonnes réponses ci-dessus et j'arrive sur ceci:

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

Cela a prouvé son efficacité, mais face à de nombreux bugs, j'ai été obligé de corriger dans plusieurs endroits de datepicker:

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

patch1: dans _showDatepicker: pour lisser la peau;

patch2: dans _checkOffset: pour corriger le positionnement du sélecteur de mois (sinon, lorsque le champ est au bas du navigateur, la vérification du décalage est désactivée);

patch3: in onClose of _hideDatepicker: sinon, lors de la fermeture, les champs de date clignoteront pendant une très courte période, ce qui est très gênant.

Je sais que ma solution était loin d'être bonne mais pour le moment ça marche. J'espère que ça aide.

5
rexwolf

J'avais besoin d'un sélecteur Mois/Année pour deux champs (De et À) et quand l'un d'entre eux était sélectionné, les valeurs Max/Min étaient définies sur l'autre ... à la cueillette des dates des billets d'avion. J'avais des problèmes pour régler le max et le min ... les dates de l'autre champ seraient effacées. Merci à plusieurs des messages ci-dessus ... J'ai finalement compris. Vous devez définir les options et les dates dans un ordre très spécifique.

Voir ce violon pour la solution complète: Choix du mois/de l’année @ JSFiddle

Code:

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

        }
    });

Ajoutez également ceci à un bloc de style comme mentionné ci-dessus:

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

Est-ce juste moi ou est-ce que cela ne fonctionne pas comme il se doit dans IE (8)? La date change lorsque vous cliquez sur Terminé, mais le sélecteur de date s'ouvre à nouveau jusqu'à ce que vous cliquiez quelque part dans la page pour perdre le focus sur le champ de saisie ...

Je cherche à résoudre ce problème.

<!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>
4
Tom Van Schoor

après avoir cherché jQueryUI.com pour datepicker, voici ma conclusion et répondez à votre question.

Premièrement, je dirais non à votre question. Vous ne pouvez pas utiliser datepicker jQueryUI uniquement pour le mois et l’année. Ce n'est pas supporté. Il n'a pas de fonction de rappel pour cela.

Mais vous pouvez le pirater pour afficher uniquement les mois et les années en utilisant css pour masquer les jours, etc. Et je pense que cela n'aura pas de sens car il faut que les dates soient cliquées pour pouvoir choisir une date.

Je peux dire que vous devez juste utiliser un autre datepicker. Comme ce que Roger a suggéré.

3
Reigel

J'ai eu le problème du sélecteur de date mélangé avec sélecteur de mois. Je l'ai résolu comme ça.

    $('.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
PYT

Si vous cherchez un sélecteur de mois, essayez ceci jquery.mtz.monthpicker

Cela a bien fonctionné pour moi.

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

Comme beaucoup d’autres, j’ai rencontré de nombreux problèmes en essayant de le faire, et seule une combinaison des solutions postées, et éventuellement un gros bidouillage pour le rendre parfait, a m'a permis de trouver une solution.

Problèmes avec d'autres solutions dans ce fil que j'ai essayé:

  1. La sélection d'une nouvelle date dans un sélecteur de date modifierait également la date (interne) des autres sélecteurs de date. Ainsi, lorsque vous rouvrez les autres (ou tentez d'obtenir leur date), ils ont une date différente de celle affichée dans l'entrée saisie. -champ.
  2. Le sélecteur de date ne se souviendrait pas de la date lors de la réouverture.
  3. Le code permettant de jongler avec les dates utilisait une sous-chaîne, de sorte qu'il n'était pas compatible avec tous les formats.
  4. "Mon sélecteur de mois" ne modifiait le champ de saisie qu'à sa fermeture, plutôt que chaque fois que les valeurs étaient modifiées.
  5. Le champ de saisie n'est pas mis à jour correctement si vous saisissez une chaîne de saisie mal formatée pour une date, puis cliquez sur "Fermer" dans le sélecteur de date.
  6. Je ne peux pas avoir les sélecteurs de date normaux, qui affichent les jours, sur la même page que les sélecteurs de mois, qui ne les affichent pas.

J'ai enfin trouvé un moyen de résoudre tous ces problèmes. Les quatre premiers peuvent être corrigés simplement en faisant attention à la façon dont vous référencez vos sélecteurs de date et de mois dans leur code interne et, bien sûr, en effectuant une mise à jour manuelle de vos sélecteurs. Vous pouvez le voir dans les exemples d'instanciation au bas de l'écran. Le cinquième problème peut être résolu en ajoutant du code personnalisé aux fonctions datepicker.

NOTE: Vous n'avez PAS besoin d'utiliser les scripts de l'outil de sélection de mois suivants pour résoudre les trois premiers problèmes de votre indicateur de date normal. Utilisez simplement le script d'instanciation de datepicker situé au bas de cet article.

Maintenant, pour utiliser les sélecteurs de mois et réparer le dernier problème, nous devons séparer les sélecteurs de dates et les sélecteurs de mois. Nous pourrions obtenir l'un des rares addons mensuels jQuery-UI, mais certains manquent de flexibilité/capacité de localisation, d'autres manquent de support d'animation ... alors, que faire? Lancez votre "propre" à partir du code datepicker! Cela vous donne un sélecteur de mois entièrement fonctionnel, avec toutes les fonctionnalités du sélecteur de date, sans afficher les jours.

J'ai fourni un script de mois et le script CSS d'accompagnement, en utilisant la méthode décrite ci-dessous, avec le code jQuery-UI v1.11.1. Copiez simplement ces extraits de code dans deux nouveaux fichiers, monthpicker.js et monthpicker.css, respectivement.


Voici le processus que j'ai suivi pour cloner le datepicker d'origine et en faire un choix mensuel

Si vous ne vous souciez pas de la façon dont j'ai fait cela, faites défiler cette section et descendez jusqu'à la ligne "Maintenant, ajoutez les sélecteurs de date et de mois à la page!"

J'ai pris tout le code javascript de jquery-ui-1.11.1.js relatif à leur datepicker, je l'ai collé dans un nouveau fichier js et remplacé les chaînes suivantes:

  • "datepicker" ==> "moispicker"
  • "Datepicker" ==> "Monthpicker"
  • "sélecteur de date" ==> "sélecteur de mois"
  • "Sélecteur de date" ==> "Sélecteur de mois"

Ensuite, j'ai supprimé la partie de la boucle for qui crée l'intégralité de la div ui-datepicker-calendar (les autres solutions masquant l'utilisation de CSS). Cela peut être trouvé dans le _generateHTML: function (inst).

Trouvez la ligne qui dit:

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

Marquez tout de après le div-tag de fermeture et jusqu'à (et pas y compris) la ligne où il est indiqué:

drawMonth++;

Maintenant, ce sera malheureux, car nous devons fermer certaines choses. Après la fermeture de la balise div précédente, ajoutez ceci:

";

Le code devrait maintenant être bien assemblé. Voici un extrait de code montrant ce que vous auriez dû vous retrouver:

...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...

Ensuite, j'ai copié/collé le code de jquery-ui.css concernant les datepickers dans un nouveau fichier CSS, et remplacé les chaînes suivantes:

  • "datepicker" ==> "moispicker"

Maintenant, ajoutez les sélecteurs de date et sélecteurs de mois à la page!

Les extraits de code javascript suivants fonctionnent avec plusieurs datepickers et/ou monthpickers sur la page, sans les problèmes susmentionnés! Corrigé généralement en utilisant '$ (this).'. beaucoup :)

Le premier script concerne un sélecteur de date normal et le second, le "nouveau" sélecteur de mois.

Le commentaire . After, qui vous permet de créer un élément pour effacer le champ d'entrée, est volé à la réponse de Paul Richards.

J'utilise le format "MM aa" dans mon sélecteur de mois et le format "aa-mm-jj" dans mon sélecteur de date, mais ceci est complètement compatible avec tous les formats, vous êtes donc libre d'utiliser celui que vous voulez. Changez simplement l'option 'dateFormat'. Les options standard 'showButtonPanel', 'showAnim' et 'yearRange' sont bien sûr optionnelles et personnalisables.


Ajout d'un datepicker

Instanciation Datepicker. Celle-ci va d'il y a 90 ans à nos jours. Cela vous aide à garder le champ de saisie correct, surtout si vous définissez les options defaultDate, minDate et maxDate, mais il peut le gérer si vous ne le faites pas. Cela fonctionnera avec n'importe quel dateFormat que vous choisissez.

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

Ajout d'un sélecteur de mois

Incluez le fichier monthpicker.js et le fichier monthpicker.css dans la page que vous souhaitez utiliser.

Instanciation du sélecteur de mois La valeur extraite de ce sélecteur de mois est toujours le PREMIER jour du mois sélectionné. Commence au mois en cours et va de 100 ans à 10 ans.

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

C'est tout! C'est tout ce dont vous avez besoin pour choisir un sélecteur de mois.

Je n'arrive pas à faire fonctionner un script avec cela, mais cela fonctionne pour moi dans mon projet ASP.NET MVC. Faites simplement ce que vous faites normalement pour ajouter un datepicker à votre page et incorporez les scripts ci-dessus, éventuellement en changeant le sélecteur (ce qui signifie $ ("#MonMonthTextBox")) pour quelque chose qui fonctionne pour vous.

J'espère que ça aidera quelqu'un.

Liens vers pastebins pour certaines configurations supplémentaires de sélecteur de date et de mois:

  1. sélecteur de mois travaillant le dernier jour du mois . La date que vous obtenez à partir de ce sélectionneur de mois sera toujours le dernier jour du mois.

  2. Deux ramasseurs de mois collaborateurs ; 'start' fonctionne le premier du mois et 'end' le dernier du mois. Ils sont tous deux limités l'un à l'autre. Le choix du mois de "fin" qui précède le mois de "début" est remplacé par "début" et correspond au même mois que "fin". Et vice versa. FACULTATIF: lors de la sélection d'un mois sur 'début', la 'minDate' sur 'fin' est définie sur ce mois. Pour supprimer cette fonctionnalité, commentez une ligne dans onClose (lisez les commentaires).

  3. Deux datepickers collaborant ; Ils sont tous deux limités l'un à l'autre, aussi, le fait de choisir une date "fin" antérieure à la date sélectionnée "début" changera "début" pour correspondre au même mois que "fin". Et vice versa. FACULTATIF: lors de la sélection d'une date sur 'début', la 'minDate' sur 'fin' est définie sur cette date. Pour supprimer cette fonctionnalité, commentez une ligne dans onClose (lisez les commentaires).

3

Si quelqu'un le souhaite également pour plusieurs calendriers, il n'est pas très difficile d'ajouter cette fonctionnalité à jquery ui. avec recherche minifiée pour:

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

ajoutez ceci devant x

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

rechercher

<table class="ui-datepicker-calendar

et le remplacer par

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

aussi rechercher

this._defaults={

le remplacer par

this._defaults={justMonth:false,

pour css, vous devez utiliser:

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

après cela, tout est fait, il vous suffit d’aller aux fonctions de datepicker init souhaitées et de définir les paramètres.

$('#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 est la clé ici :)

3
prdatur

Waht about: http://www.mattkruse.com/javascript/calendarpopup/

Sélectionnez l'exemple de sélection du mois

2
Roger

J'ai eu certaines difficultés avec la réponse acceptée et aucune autre ne pouvait être utilisée avec un minimum d'effort comme base. J'ai donc décidé de modifier la dernière version de la réponse acceptée jusqu'à ce qu'elle réponde au moins aux normes minimales de codage JS/réutilisabilité.

Voici une solution beaucoup plus propre que la ème (dernière) édition du Ben Koehler La réponse est acceptée. De plus, il va:

  • fonctionne non seulement avec le format mm/yy, mais avec tout autre format, y compris le MM yy de l'OP.
  • pas masquer le calendrier des autres datepickers sur la page.
  • ne pollue pas implicitement l’objet JS global avec les variables datestr, month, year etc.

Vérifiez-le:

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

Et tout ce dont vous avez besoin est le CSS suivant quelque part:

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

C'est ça. J'espère que ce qui précède fera gagner un peu de temps à d'autres lecteurs.

2
Alexander Abakumov

J'ai bien aimé la réponse @ user1857829 et son "approche d'extension-jquery-like-a-plugin". Je viens de faire une petite modification afin que, lorsque vous changez de mois ou d’année, le sélecteur écrive réellement la date sur le terrain. J'ai trouvé que j'aurais aimé ce comportement après l'avoir utilisé un peu.

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
stravanato

Quelques améliorations apportées à la réponse presque parfaite de BrianS ci-dessus:

  1. J'ai regexé la valeur affichée car je pense que cela la rend légèrement plus lisible dans ce cas (bien que le format utilisé soit légèrement différent)

  2. Mon client ne souhaitant pas de calendrier, j'ai donc ajouté un ajout à la classe d'affichage/masquage pour le faire sans affecter les autres sélecteurs de date. La suppression de la classe est sur une minuterie pour éviter que la table ne clignote à nouveau lorsque le sélecteur de date s'estompe, ce qui semble être très visible dans IE.

EDIT: Un problème qui reste à résoudre avec ceci est qu’il n’ya aucun moyen de vider le sélecteur de date - effacez le champ et cliquez à l’écran, il se repeuillira avec la date sélectionnée.

EDIT2: Je n’ai pas réussi à résoudre ce problème correctement (c’est-à-dire sans ajouter un bouton Clear séparé à côté de l’entrée), et j’ai fini par utiliser simplement ceci: https://github.com/thebrowser/jquery.ui.monthpicker - Si quelqu'un peut obtenir l'interface utilisateur standard pour le faire, ce serait génial.

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

Vous avez également besoin de cette règle de style:

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

J'ai essayé les différentes solutions proposées ici et elles ont bien fonctionné si vous vouliez simplement quelques menus déroulants.

Le meilleur (en apparence, etc.) 'sélecteur' ( https://github.com/thebrowser/jquery.ui.monthpicker ) suggéré ici est fondamentalement un copie d'une ancienne version de jquery-ui datepicker avec le _generateHTML réécrit. Cependant, j’ai trouvé qu’il ne jouait plus très bien avec jquery-ui (1.10.2) et présentait d’autres problèmes (ne ferme pas sur esc, ne ferme pas sur l’ouverture d’un autre widget, a des styles codés en dur).

Plutôt que d'essayer de corriger ce sélecteur de mois et de ne pas tenter à nouveau le même processus avec le dernier sélecteur de date, je me suis attaché à accrocher les parties pertinentes du sélecteur de date existant.

Cela implique de:

  • _generateHTML (pour construire le balisage du sélecteur de mois)
  • parseDate (comme il ne l'aime pas quand il n'y a pas de composant day),
  • _selectDay (comme datepicker utilise .html () pour obtenir la valeur du jour)

Comme cette question est un peu ancienne et déjà bien répondue, voici seulement le remplacement de _selectDay pour montrer comment cela a été fait:

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

Comme indiqué précédemment, il s’agit d’une question ancienne, mais j’ai trouvé cela utile, je voulais donc ajouter un retour d’information avec une solution alternative.

1
freedomn-m

Je sais que la réponse est un peu tardive, mais le même problème se posait quelques jours auparavant et je suis arrivé avec une solution simple et efficace. D'abord j'ai trouvé ce grand sélecteur de date ici

Ensuite, je viens de mettre à jour la classe CSS (jquery.calendarPicker.css) fournie avec l'exemple suivant:

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

.calDay 
{
    display:none;
}

Le plugin déclenche un événement DateChanged lorsque vous modifiez quoi que ce soit, il n’importe donc pas que vous ne cliquiez pas sur une journée (et cela correspond à Nice comme un sélecteur d’année et de mois)

J'espère que ça aide!

1
pjnovas

J'avais aussi besoin d'un sélecteur de mois. J'ai fait un simple avec l'année sur l'en-tête et 3 lignes de 4 mois ci-dessous. Découvrez-le: Sélecteur simple d'un an avec jQuery .

1
Tiago Coelho

pour un mois, en utilisant JQuery v 1.7.2, j'ai le javascript suivant qui fait exactement cela

$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
Ricardo Appleton

Merci pour la solution de Ben Koehler.

Cependant, j'ai eu un problème avec plusieurs instances de datepickers, avec certaines d'entre elles nécessaires avec la sélection du jour. La solution de Ben Koehler (dans l'édition 3) fonctionne, mais masque la sélection du jour dans tous les cas. Voici une mise à jour qui résout ce problème:

$('.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");
        }
    }
});
0
dj3c1t