Sélection d'une plage de mois avec DatePicker dans iView

Dans certains projets, on doit sélectionner une période exprimée en mois (par exemple, du mois 05/2020 au mois 07/2020). La documentation officielle d'iView indique qu'aucun type natif ne permet de choisir une plage de mois.

Une approche consiste à utiliser deux composants DatePicker de type month pour contrôler le mois de début et le mois de fin :

  1. Mise en place du code dans le template :

    <DatePicker
      type="month"
      placement="bottom-start"
      placeholder="Sélectionnez le mois de début"
      @on-change="onStartMonthChange"
      :options="startMonthOptions"
      :editable="false"
    ></DatePicker>&nbsp;&nbsp;
    <DatePicker
      type="month"
      placement="bottom-start"
      placeholder="Sélectionnez le mois de fin"
      @on-change="onEndMonthChange"
      :options="endMonthOptions"
      :editable="false"
    ></DatePicker>
    
    

    Récupération des mois sélectionnés :

    // Mise à jour du mois de début
    onStartMonthChange(month) {
      this.startMonth = month;
    },
    // Mise à jour du mois de fin
    onEndMonthChange(month) {
      this.endMonth = month;
    },
    
    
  2. Création d'une méthode utilitaire pour convertir une chaîne de mois (par ex. "2020-07") en objet Date avec le premier jour du mois :

    // Conversion d'une chaîne au format "YYYY-MM" en Date
    parseMonthToDate(strMonth) {
      let parts = strMonth.split("-");
      let month = parseInt(parts[1], 10);
      let formatted = parts[0] + "-" + month + "-1";
      let date = eval(
        "new Date(" +
          formatted
            .replace(/\d+(?=-[^-]+$)/, function(a) {
              return parseInt(a, 10) - 1;
            })
            .match(/\d+/g) +
          ")"
      );
      return date;
    },
    
    

    Note : Ajouter directement le jour "01" à la chaîne de mois provoque une erreur (ex. "2020-07" devient "2020-7-1" après transformation manuelle). La méthode ci-dessus supprime le zéro non significatif pour les mois antérieurs à octobre.

  3. Définition des options de désactivation dans data pour garantir que le mois de début est antérieur au mois de fin et que les deux sont dans le passé ou le présent :

    data() {
      return {
        startMonth: "",   // Mois de début choisi
        endMonth: "",     // Mois de fin choisi
        // Contraintes pour le sélecteur du mois de début
        startMonthOptions: {
          disabledDate: date => {
            if (this.endMonth) {
              let endDate = this.parseMonthToDate(this.endMonth);
              return (date && date > endDate) || date > new Date();
            } else {
              return date && date > new Date();
            }
          }
        },
        // Contraintes pour le sélecteur du mois de fin
        endMonthOptions: {
          disabledDate: date => {
            if (this.startMonth) {
              let startDate = this.parseMonthToDate(this.startMonth);
              return (date && date < startDate) || date > new Date();
            } else {
              return date && date > new Date();
            }
          }
        }
      };
    },
    
    

    Important : Utilisez des fonctions fléchées pour que this fasse référence à l'instance Vue dans disabledDate.

Alternative : on peut remplacer @on-change par v-model pour lier directement des objets Date. Cela évite la méthode de conversion, car on compare les dates via getTime(). Cependant, attention lors de l'envoi au serveur : il faudra peut-être formater la date.

Résultat attendu après implémentation :

  • Le mois de début ne peut pas être postérieur au mois de fin.
  • Aucun des deux mois ne peut être dans le futur.
  • Les mois antérieurs sont grisés et non sélectionnables.

Pour plus de détails, consulter la documentation officielle d'iView DatePicker.

Étiquettes: iView Vue.js DatePicker sélection de plage de mois composant UI

Publié le 27 juin à 19h22