- · Niveau : INTERMÉDIAIRE
- · Compatibilité : IIS4
- · Voir l’exemple
- · Fichier à télécharger
Que se soit pour faire une recherche parmi les jours de l’année afin de trouver un événement ou encore sélectionner une date ou simplement retourner les calendes grecques, un calendrier n’est pas toujours simple à réaliser. Créer demande réflexion, les lignes de chaque semaine, les colonnes de chacune des journées, l’en-tête... Ajouter à celui-ci un peu de dynamisme en affichant la date courante et la réflexion risque de vous faire manque le seigneur des anneaux.
Utiliser une fonction qui pourrait générer un tel tableau à volonté devient donc une évidence. Ce qui ne l’est pas c’est comment? Savoir quand changer de semaine, afficher la date courante ou encore afficher le mois courant et les mois qui le précède et le suivre est une chose. Mais savoir si le tableau comportera 4 ou 6 semaines et où afficher la première journée du mois en est une autre...
La technique que j’ai utilisée sort un peu de l’ordinaire, quelle surprise! Au lieu de fabuler en date, ce qui n’est pas mathématiquement logique, je me suis basé sur le HTML! Mon esprit cartésien s’est donc mis à l’oeuvre à chercher en premier le nombre de cases. C’est alors que j’ai trouvé une façon toute simple de générer un calendrier entièrement autonome.
Trouver le dernier jour pour identifier le nombre de cases.
Encore une fois, une méthode de mon cru toute simple qui sautait aux yeux. Le dernier jour du mois permet de trouver le nombre de cases maximum. La plupart des scripts testent le mois, identifient s’il comporte 30 ou 31 jours et isolent le mois de février pour les années bissextiles et le millénaire. D’autres encore utilisent une boucle du 28 au 31 en testant si la date est valide. En ASP il existe une fonction pour additionner et soustraire des dates. Vous me voyez venir, puisque je dois garder le premier jour en mémoire, ma première action est de trouver cette date. J’additionne à cette date 1 mois, et ensuite je supprime une journée à cette date, j’obtiens alors la dernière journée du mois!
nDate = ’ Une date valide
’ Extraction du jour, du mois et de l’annnée
nJour = Day(nDate)
nMois = Month(nDate)
nAnnee = Year(nDate)
’ Date du premier jour du mois (1)
nDate1 = DateSerial(nAnnee, nMois, 1)
’ Date du premier jour du mois suivant
nTemp = DateAdd("m", 1, nDate1)
’ Dernier jour du mois
nJour2 = Day(DateAdd("d", -1, nTemp))
’ Date du dernier jour du mois
nDate2 = DateSerial(nAnnee, nMois, nJour2)
Trouver le nombre total de cases
Voilà, il ne reste plus qu’à identifier le jour de la semaine de ses deux dates pour obtenir leur position et le nombre total de cases. Ainsi, tous nos éléments sont en place pour générer un calendrier. N’est-ce pas simple ?
’ Jour de la semaine du premier jour
nDateDebut = WeekDay(nDate1, vbSunday)
’ Jour de la semaine du dernier jour
nDateFin = WeekDay(nDate2, vbSunday)
’ Nombre total de cases
nbrCase = Day(nDate2) + (nDateDebut-1) + (7-nDateFin)
Et oui, encore une fois ça sautait aux yeux. Par chance dans ce dédale de nombres, une chose reste fiable, il y a toujours 7 jours dans une semaine. Et puisque ASP nous retourne le nombre qui indique le jour de la semaine, il suffit des additionner au nombre total de jours en prenant bien soin d’enlever les jours réellement occupés.
Construire le calendrier
Pour laisser l’éternité à son destin et ne pas m’embourber dans sa poussière, je vais laisser passer les deux premières lignes, soit le nom du mois et l’en-tête de chaque journée pour me concentrer sur le calendrier en tant que tel. Une seule boucle, de 1 au nombre total de cases. C’est là l’astuce enfin! Pour bien identifier les jours des cases, une variable temporaire contient (le compteur - la position du premier jour + 1). Ce nombre temporaire est le jour de la date réelle de chaque position, elle sera donc plus petite à 1 avant sa première position et plus grande que la position de la dernière journée. Une autre variable temporaire "nNomJour" gardera quant à elle les jours de la semaine, soit de 1 à 7.
Noter que le tableau HTML utilise le CSS. La classe "calJourSel" identifie la date courante alors que "calJour" identifie les autres jours.
<%
Dim njTemp, nNomJour
nNomJour = 1
’ Boucle de 1 au nombre total de cases
For n = 1 to nbrCase
’ Récupérer la date réelle
njTemp = n - nDateDebut+1
’ Nouvelle ligne à chaque semaine
if nNomJour = 1 then response.write "<tr>" end if
’ Nouvelle case
’ SI le jour de la date réelle = le jour de la date courante
’ SINON, autre jour
if (njTemp) = nJour then
response.write "<td align=""center"" valign=""middle"" class=""calJourSel"">"
else
response.write "<td align=""center"" valign=""middle"" class=""calJour"">"
end if
’ SI le compteur est plus petit que la première journée
’ ou se le compteur est plus grand que le dernier jour
’ aucun affichage
’ SINON, affichage du jour réel temporaire
if n < (nDateDebut) or n > (nJour2+nDateDebut-1) then
response.write " "
else
’ SI le jour de la date réelle = le jour de la date courante
’ affichage du jour réel temporaire
’ SINON, afficher aussi un lien vers le jour temporaire
if (njTemp) = nJour then
response.write (njTemp)
else
response.write "<a href="""&nURL&"?date="&DateSerial(nAnnee, nMois, njTemp)&""">"
response.write (njTemp) & "</a>"
end if
end if
’ Fin de case
response.write "</td>"
’ Ajuster le jour de la semaine
’ SI le jour de la semaine = 7, fin de ligne et remettre à 1
’ SINON, aditionner 1
if nNomJour = 7 then
response.write "</tr>"
nNomJour = 1
else
nNomJour = nNomJour + 1
end if
next ’ Boucle des jour
%>
Le nom du mois, et les mois précédent et suivant
C’est tout ! En se basant sur le nombre de cases, les seules choses à se rappeler sont les positions du premier et du dernier jour... Le reste est entièrement basé sur ces deux nombres. Ma fonction "twCalende.asp" identifie en plus les mois précédent et suivant pour changer de mois et utilise bien sûr un tableau (array) des noms des journées et mois en français. Tant qu’à faire, pourquoi pas une petite variable pour identifier la langue et ainsi avoir un calendrier bilingue...
Les liens hypertexte
J’utilise la variable serveur "URL" qui contient celui de la page courante, il suffit alors de copier ce code dans n’importe quelle page pour qu’il soit fonctionnel sans ajuster cette variable manuellement. C’est d’ailleurs une bonne façon que de traiter une requête HTTP sur la même page pour ainsi éviter les problèmes de page précédente... La date courante est récupérée par le paramètre "date", s’il n’y a pas de paramètre, elle sera la date courante du système.
nURL = Request.ServerVariables("URL")
Remqarque sur le HTML versu le ASP
J’aurais pu créer une fonction d’un seul bloc pour n’avoir qu’un copier/coller à faire et même mettre cette fonction dans un fichier externe. Mais le ASP est plus rapide imbriqué dans le HTML. Par exemple, le "response.write" ralentit le processus. Rien ne vous empêche d’entièrement créer le calendrier à l’aide de "response.write", c’est à votre goût.
Remarque sur la table HTML et la compatibilité
Noter aussi que j’utilise le TH pour l’en-tête mais que je n’utilise pas les nouvelles normes de la W3C, à savoir le THEAD, TBODY et TFOOT. C’est que leur utilisation cause des problèmes avec plusieurs navigateurs de version 3 et même 4. Notamment, le style du TH est ignoré, ou encore le TFOOT qui doit être placé après le THEAD (et apparaître après le TBODY) est tout simplement placé avant le TBODY dans IE3. Opera ne comprend plus le CSS dans les THEAD, TBODY et TFOOT, de plus l’alignement bogue. Un jour viendra...
La feuille de styles
Le code complet à télécharger comprend 6 styles à ajuster selon vos besoins pour créer un calendrier à vos couleurs. Chaque style défini la couleur de fond des cellules, la couleur, la grandeur, l’alignement et la police du texte. Pour rendre le calendrier compatible à la plupart des navigateurs de version 3+, voir 2+, remplacer les styles par des couleurs HTML directement dans le tableau. Attention à Netscape si le tableau est déjà dans d’autres tableaux avec couleurs.
TH.calMois | L’en-tête qui indique le mois courant. |
TD.calSing | La dernière ligne avec le lien Trucsweb |
TD.calSemaine | L’en-tête qui indique les journées de la semaine |
TD.calJour | Chaque jour du mois (les cases) |
TD.calJour A | Les liens de chaque jour |
TD.calJour A:hover | Les liens réactifs (RollOver) de chaque jour |
TD.calJourSel | Le jour courrant |