L'élément <input> de type month crée un champ d'entrée permettant d'entrer facilement un mois et une année.

L'interface de contrôle varie en général d'un navigateur à l'autre; pour le moment la prise en charge est inégale, avec seulement Chrome/Opera et Edge sur ordinateur — et les navigateurs modernes les plus récents — ayant des implémentations utilisables. Dans d'autres navigateurs, le contrôle dégrade à un simple <input type="text">.

<input id="month" type="month">

Pour ceux d'entres vous n'utilisant pas un navigateur supporté, l'interface pour Chrome/Opera ressemble à la capture d'écran ci-dessous. Un clic sur la flèche vers le bas sur le côté droit fait apparaître un sélecteur de date vous permettant de choisir une date : vous devez entrer l'heure manuellement.

L'interface sous Edge pour month ressemble à ceci :

Valeur Un élément DOMString représentant un mois et une année, ou vide.
Évènements change et input.
Prise en charge des attributs communs autocomplete, list, readonly, et step.
Attribut IDL value.
Méthodes select(), stepDown(), stepUp().

Valeur

Un élément DOMString représentant la valeur du mois et de l'année entrée dans le champ. Vous pouvez définir une valeur par défaut pour le champ en incluant une date dans l'attribut  value, comme ceci :

<label for="bday-month">What month were you both in?</label>
<input id="bday-month" type="month" name="bday-month" value="2017-06">

Une chose à noter est que le format de date affiché diffère de la valeur réelle — le format de la date affichée sera basé sur l’ensemble des paramètres régionaux du système d’exploitation de l’utilisateur, alors que la date de valeur sera toujours au format aaaa-mm. Lorsque la valeur sera envoyée au serveur, par exemple, elle ressemblera à bday-mont=1978-06.

Vous pouvez également définir la valeur de la date en JavaScript en utilisant la propriété HTMLInputElement.value, par exemple :

var monthControl = document.querySelector('input[type="month"]');
monthControl.value = '1978-06';

Utilisations du champ mois

Les entrées liées à la date sont commodes à première vue, ils fournissent une interface utilisateur facile pour choisir les dates, et ils normalisent le format de données envoyé au serveur, quelle que soit la langue de l’utilisateur. Cependant, il y a des problèmes avec <input type="month"> en raison du support limité des navigateurs.

Nous allons regarder les utilisations basiques et plus complexe de <input type="month">, et ainsi donner des conseils sur l’atténuation du problème de support du navigateur par la suite (voir Handling browser support).

Utilisation basiques du mois

La plus simple utilisation de <input type="month"> est un simple <input> et impliquant l'élément <label> combiné, comme ci-dessous :

<form>
  <label for="bday-month">What month were you both in?</label>
  <input id="bday-month" type="month" name="bday-month">
</form>

Paramétrer une date maximum et minimum

Vous pouvez utiliser l'attribut min et max pour restreindre les dates pouvant être choisies par l'utilisateur. Dans l'exemple suivant, nous avons paramétrés un mois minimum à 1900-01 et un maximum à 2017-08:

<form>
  <label for="bday-month">What month were you both in?</label>
  <input id="bday-month" type="month" name="bday-month"
         min="1900-01" max="2017-08">
</form>

Le résultat est que :

  • Seulement les mois entre janvier 1900 et août 2017 peuvent être sélectionnés —  les mois en dehors de cette plage ne peut pas être défile dans le contrôle.
  • Selon le navigateur que vous utilisez, vous pourriez constater que les temps en dehors des valeurs spécifiées pourraient ne pas être sélectionnés dans le sélecteur de temps (par exemple Edge), ou non valide (voir Validation) mais toujours disponibles (p. ex. Chrome).

Note: Vous pourriez être capable à utiliser l'attribut step pour varier le nombre de jour sauté chaque fois que la date est incrémenté (ex. peut-être voudriez-vous rendre uniquement le samedi séléctionnable). Toutefois, cela ne semble pas fonctionner efficacement dans n’importe quelle implémentation au moment de l'écriture de cet article.

Contrôler la taille de l'entrée

<input type="month"> ne supporte pas les attributs de dimensionnement de forme comme size. Vous devrez avoir recours à CSS pour redimensionner selon vos besoins.

Validation

Par défaut, <input type="month"> n'applique aucune validation sur les valeurs entrées. Les implémentations de l’interface utilisateur ne vous laissent généralement pas entrer quelque chose qui n’est pas une date — ce qui est utile — mais vous ne pourriez pas remplir une date et soumettre, ou entrez une date non-valide (par exemple le 32 du mois d’avril).

Vous pouvez utiliser min et max pour restreindre les dates valables (voir Paramétrer une date maximum et minimum), et en ajoutant l'utilisation de l'attribut required pour faire un champ date obligatoire. Comme résultat, les navigateurs supportés afficheront une erreur si vous tentez d'envoyer une date en dehors des limites définies, ou un champ date vide.

Regardons un exemple — où nous avons défini une date minimum et maximum, et aussi rendu le champ obligatoire :

<form>
  <div>
    <label for="month">What Month would you like to visit us? (Summer months only.)</label>
    <input id="month" type="month" name="month"
           min="2017-06" max="2017-09" required>
    <span class="validity"></span>
  </div>
  <div>
      <input type="submit" value="Submit form">
  </div>
</form>

Si vous tentez d'envoyer ce formulaire avec une date incomplète (ou avec une date en dehors des limites), votre navigateur affichera une erreur. Essayez de jouer avec l'exemple :

Ici, une capture d'écran pour ceux qui n'utiliserait pas un navigateur compatible :

Voici le CSS utilisé dans l’exemple ci-dessus. Ici nous faisons usage des propriétés :valid et :invalid pour modifier l'apparence du champ basée, si oui ou non, la valeur courante est valide. Nous avons dû mettre les icônes sur un élément <span> à côté de l’entrée, pas sur l’entrée elle-même, car sur Chrome le contenu généré est placé à l’intérieur du champ et ne peut être modifié ou affiché efficacement.

div {
  margin-bottom: 10px;
  position: relative;
}

input[type="number"] {
  width: 100px;
}

input + span {
  padding-right: 30px;
}

input:invalid+span:after {
  position: absolute;
  content: '✖';
  padding-left: 5px;
}

input:valid+span:after {
  position: absolute;
  content: '✓';
  padding-left: 5px;
}

Important: La validation du formulaire HTML n’est pas un substitut pour les scripts qui s’assurent que les données saisies sont dans le format approprié.  Il est beaucoup trop facile pour quelqu'un d'apporter des modifications dans le code HTML qui leur permettent de contourner la validation, ou de le supprimer entièrement. Il est aussi possible pour quelqu'un de simplement contourner votre HTML entièrement et envoyer les données directement sur votre serveur. Si votre code côté serveur ne parvient pas à valider les données qu’il reçoit, une catastrophe pourrait frapper lors de l’envoi de données formatées incorrectement.

Prise en charge du navigateur

Comme mentionner précédemment, le problème majeur avec l'utilisation des champs de type date au moment où nous écrivons cet article est le support des navigateurs — seulement avec Chrome/Opera et Edge pour les ordinateurs, ainsi que les navigateurs mobiles les plus modernes. À titre d'exemple, le sélectionneur month ressemble à ceci sur Chrome pour Android :

Les navigateurs non supportés dégrade gracieusement le champ à un simple champ texte, mais cela crée des problèmes à la fois en termes de cohérence de l’interface utilisateur (le contrôle présenté sera différent) et la manipulation de données.

Le second problème est plus sérieux — comme nous le mentionnons plus tôt, avec un champ month, la valeur actuelle est toujours normalisée au format aaaa-mm. Avec un champ texte, par défaut le navigateur n’a aucune connaissance du format de la date dont elle devrait être, et il y a plusieurs formats dans lesquels les gens écrivent des dates, comme par exemple :

  • mmaaaa
  • mm/aaaa
  • mm-aaaa
  • aaaa-mm
  • etc.

Un moyen de contourner ceci est de mettre un attribut pattern sur votre champ de type mois. Même si l’entrée month n’est pas utiliser, le champ text de secours le sera. Par exemple, essayez d’afficher la démo suivante dans un navigateur non supporté :

<form>
  <div>
    <label for="month">What Month would you like to visit us? (Summer months only, yyyy-mm)</label>
    <input id="month" type="month" name="month"
           min="2017-06" max="2017-09" required
           pattern="[0-9]{4}-[0-9]{2}">
    <span class="validity"></span>
  </div>
  <div>
      <input type="submit" value="Submit form">
  </div>
</form>

Si vous essayez de l'envoyer, vous verrez que le navigateur affichera maintenant un message d'erreur (et mettre en surbrillance le champ invalide) si votre entrée ne correspond pas avec le motif nnnn-nn, où n est un nombre de 0 à 9. Bien sûr, ceci n'arrêtera personne d'entrer une date invalide, ou un format de date ne correspondant pas au motif.

Et est-ce que l’utilisateur va comprendre le motif dont il a besoin pour entrer la date ?

Nous avons toujours un problème.

La meilleure façon de traiter avec des dates dans un formulaire pour plusieurs navigateurs pour le moment est de donner à l’utilisateur la possibilité d’entrer le mois et l’année dans des contrôles distincts (<select> — voir ci-dessous pour une mise en œuvre), ou d'utiliser des bibliothèques JavaScript telles que jQuery date picker,  et le plugin jQuery timepicker.

Exemples

Dans cet exemple nous créerons deux ensembles d'interfaces pour choisir une date — un sélectionneur natif créer avec le champ month, et un ensemble de deux éléments <select> pour choisir le mois et l'année dans d'anciens navigateurs ne supportant pas le champ natif.

Le code HTML ressemblera à ceci :

<form>
  <div class="nativeDatePicker">
    <label for="month-visit">What Month would you like to visit us?</label>
    <input type="month" id="month-visit" name="month-visit">
    <span class="validity"></span>
  </div>
  <p class="fallbackLabel">What Month would you like to visit us?</p>
  <div class="fallbackDatePicker">
    <div>
      <span>
        <label for="month">Month:</label>
        <select id="month" name="month">
          <option selected>January</option>
          <option>February</option>
          <option>March</option>
          <option>April</option>
          <option>May</option>
          <option>June</option>
          <option>July</option>
          <option>August</option>
          <option>September</option>
          <option>October</option>
          <option>November</option>
          <option>December</option>
        </select>
      </span>
      <span>
        <label for="year">Year:</label>
        <select id="year" name="year">
        </select>
      </span>
    </div>
  </div>
</form>

Les mois sont écrit en dur (comme ils seront toujours les mêmes), avec l'année dynamiquement générée selon l'année en cours (voir le code commenté plus bas pour plus d'explications détaillées sur son fonctionnement).

L’autre partie du code dont l'intérêt est le code de détection des fonctionnalité — pour détecter si le navigateur prend en charge <input type="month">, nous créerons un nouvel élément <input>, définissez son type sur month, puis vérifier immédiatement de quel type il est — les navigateurs non supportés retourneront un champ de type text, parce que le type date retourne le champ en type text. Si <input type="month"> n'est pas pris en charge, nous masquons le sélecteur natif et affichons le sélecteur de secours (<select>) à la place.

// define variables
var nativePicker = document.querySelector('.nativeDatePicker');
var fallbackPicker = document.querySelector('.fallbackDatePicker');
var fallbackLabel = document.querySelector('.fallbackLabel');

var yearSelect = document.querySelector('#year');
var monthSelect = document.querySelector('#month');

// hide fallback initially
fallbackPicker.style.display = 'none';
fallbackLabel.style.display = 'none';

// test whether a new date input falls back to a text input or not
var test = document.createElement('input');
test.type = 'month';
// if it does, run the code inside the if() {} block
if(test.type === 'text') {
  // hide the native picker and show the fallback
  nativePicker.style.display = 'none';
  fallbackPicker.style.display = 'block';
  fallbackLabel.style.display = 'block';

  // populate the years dynamically
  // (the months are always the same, therefore hardcoded)
  populateYears();
}

function populateYears() {
  // get the current year as a number
  var date = new Date();
  var year = date.getFullYear();

  // Make this year, and the 100 years before it available in the year <select>
  for(var i = 0; i <= 100; i++) {
    var option = document.createElement('option');
    option.textContent = year-i;
    yearSelect.appendChild(option);
  }
}

Spécifications

Specification Status Comments
HTML Living Standard
La définition de '<input type="month">' dans cette spécification.
Standard évolutif  

Compatibilité des navigateurs

Fonctionnalité Chrome Edge Firefox (Gecko) Internet Explorer Opera Safari
Support basique 20 12 Pas de support[1] Pas de support 10.62 Pas de support[2]
Fonctionnalité Android Chrome pour Android Edge Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Support basique (Oui) (Oui) (Oui) (Oui) ? (Oui) (Oui)

[1] Cette fonctionnalité n'est pas encore implémentée. Voir bug 888320 et TPE DOM/Date time input types.

[2] Il est reconnu mais ne propose pas d'intérface.

Voir aussi

Étiquettes et contributeurs liés au document

 Contributeurs à cette page : loganblangenois
 Dernière mise à jour par : loganblangenois,