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 :
-
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> <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; }, -
Création d'une méthode utilitaire pour convertir une chaîne de mois (par ex. "2020-07") en objet
Dateavec 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.
-
Définition des options de désactivation dans
datapour 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
thisfasse référence à l'instance Vue dansdisabledDate.
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.