Les éléments <input> dont l'attribut type vaut week permettent de créer des champs de saisie où l'on peut saisir une année et le numéro de la semaine pendant cette année (allant de 1 à 52).

L'interface utilisateur offerte par un tel contrôle varie en fonction des navigateurs. Au moment où nous écrivons ces lignes, seuls Chrome/Opera et Edge prennent en charge cette fonctionnalité. Pour les navigateurs qui ne l'implémentent pas, l'élément est interprété comme un élément <input type="text">.

<input id="week" type="week">

Sous Chrome/Opera, le contrôle week fournit des emplacements pour les deux valeurs. Un calendrier est affiché afin de sélectionner plus faiclement la semaine et l'année. Un bouton avec une croix permet de supprimer la valeur saisie dans le contrôle.

Pour Edge, le contrôle associé à month est plus élaboré et se compose de deux listes qu'on peut faire défiler séparement pour la semaine d'une part et l'année d'autre part.

Valeur Une chaîne de caractères (DOMString) qui représente une semaine et une année ou la chaîne vide.
Évènements change et input.
Attributs pris en charge autocomplete, list, readonly et step.
Attributs IDL value, valueAsDate, valueAsNumber, list.
Méthodes select(), stepDown(), stepUp().

Valeur

Une chaîne de caractères (DOMString) qui représente la valeur de la semaine et de l'année saisies dans le champ. Il est possible de définir une valeur par défaut grâce à l'attribut value de la façon suivante :

<label for="week">À quelle semaine souhaiteriez-vous démarrer ?</label>
<input id="week" type="week" name="week" value="2017-W01">

On notera que le format affiché peut être différent de la valeur réellement utilisée pour l'attribut value. Cette dernière respecte toujours le format yyyy-Www (soit les quatre chiffres de l'année, suivi d'un tiret, suivi d'un W majuscule suivi des deux chiffres pour la semaine). Dans l'exemple précédent par exemple, l'interface utilisateur pourra afficher Semaine 01 de l'année 2017 mais la valeur envoyée via le formulaire aura toujours la structure week=2017-W01.

Il est également possible d'accéder à la valeur ou de la définir en JavaScript grâce à la propriété HTMLInputElement.value. Par exemple :

var weekControl = document.querySelector('input[type="week"]');
weekControl.value = '2017-W45';

Utiliser les contrôles de type week

Ces contrôles peuvent être pratiques selon certains aspects : ils permettent de sélectionner une semaine de façon simple, les données envoyées au serveur sont normalisées quelle que soit la langue ou le navigateur de l'utilisateur. Toutefois, en raison de la prise en charge des navigateurs actuellement limitée, <input type="week"> pose quelques défis.

Nous verrons par la suite quelques cas d'utilisation simples puis complexes avant de voir comment gérer l'hétérogénéité des différents navigateurs (cf. Gérer la prise en charge des navigateurs).

Utilisation simple

La forme la plus simple de <input type="week"> se compose d'un élément <input> et d'un élément  <label> :

<form>
  <label for="week">À quelle semaine souhaiteriez-vous commencer ?</label>
  <input id="week" type="week" name="week">
</form>

Contrôler la taille du champ

<input type="week"> ne prend pas en charge des attributs de dimensionnement (tel que size). Il sera nécessaire d'utiliser CSS si on a besoin de modifier la taille du contrôle.

Utiliser l'attribut step

En théorie, l'attribut step devrait pouvoir être employé pour définir l'incrément minimal entre chaque semaine sélectionnable. Toutefois, il ne semble avoir encore aucun effet pour les navigateurs qui prennent en charge ce contrôle.

Validation

Par défaut, <input type="week"> n'applique aucune validation aux valeurs saisies. Les interfaces utilisateurs affichées ne permettent pas de saisir autre chose qu'un couple semaine / année. Toutefois, il est toujours possible de ne sélectionner aucune valeur, on peut également vouloir restreindre la plage de semaines qui peuvent être sélectionnées.

Paramétrer des semaines minimum et maximum

Les attributs min et max peuvent être utilisés afin de restreindre les semaines qui peuvent être sélectionnées par l'utilisateur. Dans l'exemple qui suit, on indique une valeur minimale correspondant à la première semaine de 2017 et une valeur maximale correspondant à la dernière semaine de 2017 :

<form>
  <label for="week">À quelle semaine souhaiteriez-vous commencer ?</label>
  <input id="week" type="week" name="week"
         min="2017-W01" max="2017-W52">
  <span class="validity"></span>
</form>

Voici la feuille de style utilisée dans l'exemple précédent. Vous pourrez noter qu'on utilise les pseudo-classes :valid et :invalid afin de mettre en forme le contrôle selon que la valeur saisie est valide ou non. Les icônes associées sont placées dans un élément <span> situé à côté du champ et non sur le champ même car, pour Chrome, le contenu généré dynamiquement avec les pseudo-éléments serait placé dans le contrôle du formulaire et ne pourrait être mis en forme 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;
}

Pour les navigateurs qui prennent en charge ce contrôle et ces fonctionnalités, on ne pourra sélectionner que les semaines de l'année 2017.

Rendre la valeur obligatoire

On peut aussi utiliser l'attribut required afin que la saisie de la valeur soit obligatoire. Pour les navigateurs qui prennent en charge cette fonctionnalité, une erreur sera affichée lorsqu'on tentera d'envoyer un formulaire avec un champ vide pour une semaine.

Prenons un autre exemple (où la période a été restreinte comme précédemment) et où le champ est obligatoire :

<form>
  <div>
    <label for="week">À quelle semaine souhaiteriez-vous commencer ?</label>
    <input id="week" type="week" name="week"
         min="2017-W01" max="2017-W52" required>
    <span class="validity"></span> 
  </div>
  <div>
      <input type="submit" value="Envoyer le formulaire">
  </div>
</form>

Si vous essayez de soumettre le formulaire sans aucune valeur, le navigateur affichera une erreur. Vous pouvez tester avec l'exemple qui suit :

Voici une capture d'écran du résultat obtenu si votre navigateur ne prend pas en charge cette fonctionnalité :

Important : la validation des données du formulaire HTML par le navigateur ne se substitue pas à la validation des données reçues côté serveur. En effet, il est tout à fait possible pour un utilisateur de modifier le HTML côté client et de passer outre les contraintes normalement appliquées. Il est également possible d'envoyer des données au serveur sans passer par le formulaire. Ne pas vérifier les données reçues côté serveur expose à des risques d'erreur voire d'attaques.

Gérer la prise en charge des navigateurs

Comme évoqué plus haut, le principal problème associé à ce type de contrôle est l'absence de prise en charge par Safari, Firefox (hors mobile) et les anciennes versions d'Internet Explorer (pré-Edge).

Les plateformes mobiles comme Android et iOS fournissent un contrôle natif à l'ergonomie tactile adaptée. Voici par exemple le sélecteur week sur Chrome pour Android :

Les navigateurs qui ne prennent pas en charge ce type de contrôle l'interprètent comme un champ texte mais cela crée des problèmes de cohérence tant au niveau de l'ergonomie qu'au niveau de la représentation des données.

C'est ce deuxième aspect qui peut poser le plus de problème. Comme nous l'avons mentionné avant, un contrôle week verra sa valeur normalisée pour respecter le format yyyy-Www. En revanche, pour un champ texte non reconnu par le navigateur, les utilisateurs pourraient saisir des semaines selon une variété de formats :

  • Première semaine de 2017
  • Du 2 au 8 janvier 2017
  • 2017-W01
  • etc.

Si on souhaite gérer cette saisie de façon compatible entre les différents navigateurs, on utilisera alors deux contrôles distincts (représentés par des éléments <select>) qui représenteront respectivement le numéro de la semaine et l'année.

Exemples

Dans l'exemple qui suit, on construit deux ensembles d'éléments pour sélectionner une semaine : un sélecteur natif avec <input type="week"> et un second composé de deux éléments <select> qui permettent de choisir la semaine et l'année sur les navigateurs qui ne prennent pas en charge le contrôle natif.

Voici le code HTML utilisé :

<form>
  <div class="nativeWeekPicker">
    <label for="week">À quelle semaine souhaiteriez-vous commencer ?</label>
    <input id="week" type="week" name="week"
           min="2017-W01" max="2018-W52" required>
    <span class="validity"></span>
  </div>
  <p class="fallbackLabel">À quelle semaine souhaiteriez-vous commencer ?</p>
  <div class="fallbackWeekPicker">
    <div>
      <span>
        <label for="week">Semaine :</label>
        <select id="fallbackWeek" name="week">
        </select>
      </span>
      <span>
        <label for="year">Année :</label>
        <select id="year" name="year">
          <option value="2017" selected>2017</option>
          <option value="2018">2018</option>
        </select>
      </span>
    </div>
  </div>
</form>

On génère les valeurs des semaines dynamiquement.

Dans le fragment de code JavaScript qui suit, on montre comment détecter si la fonctionnalité est prise en charge ou non. Pour cela, on crée un nouvel élément <input> et on règle son type sur week puis on vérifie immédiatement la valeur de son type. Les navigateurs qui ne prennent pas en charge la fonctionnalité renverront text. Si c'est le cas, on masque le sélecteur natif et on affiche le sélecteur alternatif composé des deux éléments <select>.

// On définit certaines variables
var nativePicker = document.querySelector('.nativeWeekPicker');
var fallbackPicker = document.querySelector('.fallbackWeekPicker');
var fallbackLabel = document.querySelector('.fallbackLabel');

var yearSelect = document.querySelector('#year');
var weekSelect = document.querySelector('#fallbackWeek');

// À l'état initial, on masque le sélecteur alternatif
fallbackPicker.style.display = 'none';
fallbackLabel.style.display = 'none';

// On teste si le sélecteur natif se transforme en 
// contrôle de saisie de texte ou non
var test = document.createElement('input');
test.type = 'week';
// Si c'est le cas, on exécute le code dans le bloc
// conditionnel if() {}
if(test.type === 'text') {
  // On masque alors le sélecteur natif et 
  // on affiche le sélecteur alternatif
  nativePicker.style.display = 'none';
  fallbackPicker.style.display = 'block';
  fallbackLabel.style.display = 'block';

  // On ajoute les semaines dynamiquement
  populateWeeks();
}

function populateWeeks() {
  // On ajoute 52 semaines grâce à une boucle
  for(var i = 1; i <= 52; i++) {
    var option = document.createElement('option');
    option.textContent = (i < 10) ? ("0" + i) : i;
    weekSelect.appendChild(option);
  }
}

Spécifications

Spécification État Commentaires
HTML Living Standard
La définition de '<input type="week">' dans cette spécification.
Standard évolutif  

Compatibilité des navigateurs

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

[1] Actuellement, cette fonctionnalité n'est pas implémentée (cf. bug 888320 et les types de saisie TPE DOM/Date time.

Voir aussi

Étiquettes et contributeurs liés au document

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