Un configurateur de calendrier Javascript est disponible si vous cherchez quelque chose de plus facile à intégrer.
Dans le cadre du développement de mon CMS, j'avais besoin de créer un simple sélecteur de date en Javascript. Je ne cherchais rien de compliqué, juste quelque chose de léger, d'autonome, qui affiche un calendrier et qui permette de naviguer entre les mois.
Comme on est jamais aussi bien servi que par soi-même voici les résultats de mon expérimentation.
jsSimpleDatePickr est un sélecteur de date javascript gratuit
(voir conditions d'utilisation en bas de page)
- Léger (2 069 octets non compressé)
- Simple et rapide
- Capable de fonctionner sans librairie externe
- Interprête les dates au format JJ, JJ/MM, JJ/MM/AA, JJ/MM/AAAA
- Capable d'ajouter ou de soustraire des mois ou des années
- Stylisé entièrement en CSS
- Testé sur Safari (5.1), Firefox (25.0), Internet Explorer (7, 8), Chrome (31)
Historique
Vendredi 25 juillet 2014
Correction d'un petit bug ligne 38
for(i in me.dayOrder){
Devient
for(var i in me.dayOrder){
la variable i reste locale et ne sera pas réutilisée par d'autres fonctions.
Merci à jecmusic d'avoir fait remonté le bug.
Dimanche 2 février 2014
Il y avait un petit bug dans le fichier jsSimpleDatePickrInit.js à la ligne 43
for(nb=0; nb<me.dayOrder.charAt(d.getDay()); nb++){
Il ne faut pas utiliser la fonction charAt mais indexOf :
for(nb=0; nb<me.dayOrder.indexOf(d.getDay()); nb++){
Le code commenté dans cet article n'avait pas cette erreur.
Mardi 14 janvier 2014
La variable fundDateChoose a été modifié en funcDateClic.
La fonction de retour renvoi la date sélectionné et l'identifiant de l'objet jsSimpleDatePickr. Il est possible d'utiliser plusieurs calendrier dans une même page HTML.
J'ai écrit un ensemble de fonction qui permet de simplifier la création du calendrier. Une ligne de code suffit ! Voir l'article sur jsSimpleDatePickrInit.js
Le code
function jsSimpleDatePickr(id){
var me = this; // enregistre l'objet
me.dateDisp = new Date(); // date d'affichage
me.dateSel = new Date(); // date sélectionnée
me.dayOrder = '1234560'; // ordre des jours. Sous forme de String plutôt que d'Array car Internet Explorer ne sait pas gérer indexOf() en version 7, 8, 9
me.dayName = ['D', 'L', 'M', 'M', 'J', 'V', 'S']; // nom de jours. Il faut commencer par le dimanche
me.id = id; // identifiant de l'élément HTML dans lequel le calendrier sera affiché
me.funcDateClic = me.classTable = me.classTd = me.classSelection = '';
// funcDateClic est la fonction qui sera appelé lors d'un clic sur une date, en passant la date en paramètre sous la forme JJ/MM/AAAA.
// classTable est le nom de la classe utilisé pour le tableau du calendrier
// classTd est le nom de la classe utilisé pour les cellules du calendrier qui contiennent un jour du mois affiché.
// classSelection est le nom de la classe utilisé pour le jour sélectionné
Initialisation des variables. La fonction attend un paramètre. L'identifiant de l'élément HTML dans lequel le calendrier sera affiché.
me.setDate = function(dateStr){
if(!dateStr) return 0;
var dateArr = dateStr.split('/');
if(isNaN(dateArr[0])) return 0;
today = new Date();
if(isNaN(dateArr[1])) dateArr[1] = today.getMonth();
else dateArr[1] = parseInt(dateArr[1], 10)-1;
if(isNaN(dateArr[2])) dateArr[2] = today.getFullYear();
else if(parseInt(dateArr[2], 10)<100) dateArr[2] = parseInt(dateArr[2], 10)+2000;
me.dateSel = new Date(dateArr[2], dateArr[1], dateArr[0]);
me.dateDisp = new Date(dateArr[2], dateArr[1], dateArr[0]);
}
La fonction setDate() permet de convertir une date sous forme de texte en objet javascript Date().
La date attendu est au format JJ/MM/AAAA, mais la fonction est souple.
Elle commence par convertir le String en Array avec la fonction split('/'). Théoriquement on doit avoir un Array avec trois entrées [0=>JJ, 1=>'MM', 2=>'AAAA'] :
- Si le jour n'est pas défini isNaN(dateArr[0]), on retourne 0. Il faut quand même un minimum !
- Si le mois n'est pas défini isNaN(dateArr[1]), on utilise le mois actuel.
- Si l'année n'est pas définie isNaN(dateArr[2]), on utilise l'année actuelle. Si l'année est inférieure à 100, on considère qu'on est après l'an 2000, donc on ajoute 2000.
Cela permet à la fonction d'utiliser des dates au format variés. Par exemple si nous étions en Mars 2014 :
- '5' = '5/3/2014'
- '5/3' = '5/3/2014'
- '5/3/15' = '5/3/2015'
- '5/3/2015' = '5/3/2015'
me.setMonth = function(val){
var v = parseInt(val, 10);
if(val.charAt(0)=='+' || val.charAt(0)=='-') v = me.dateDisp.getMonth()+v;
me.dateDisp.setMonth(v);
}
setMonth() permet de changer le mois :
- soit en additionnant des mois: setMonth('+1'), setMonth('+3')
- soit en soustrayant des mois: setMonth('-1'), setMonth('-4')
- soit en fixant le mois : setMonth('0') pour janvier, setMonth('1') pour février, etc…
La fonction setMonth() attend un String en paramètre.
me.setYear = function(val){
var v = parseInt(val, 10);
if(val.charAt(0)=='+' || val.charAt(0)=='-') v = me.dateDisp.getFullYear()+v;
me.dateDisp.setFullYear(v);
}
La fonction setYear() est comme setMonth(), mais fonctionne pour les années. Il est possible d'additionner, de soustraire ou de définir l'année.
me.show = function(){
var nb = today = 0;
var month = me.dateDisp.getMonth();
var year = me.dateDisp.getFullYear();
// #1 vérifie si le jour sélectionné fait parti du mois affiché
if(month==me.dateSel.getMonth() && year==me.dateDisp.getFullYear()) today = me.dateDisp.getDate();
var h = '<table class="'+me.classTable+'"><tr>';
// #2 affiche les noms des jours
for(var i in me.dayOrder){
h += '<th>'+me.dayName[me.dayOrder[i]]+'</th>';
}
h += '</tr><tr>';
// #3 affiche les premières cellules vide du mois
var d = new Date(year, month, 1);
for(nb=0; nb<me.dayOrder.indexOf(d.getDay()); nb++){
h += '<td> </td>';
}
// #4 cherche le dernier jour du mois
d.setMonth(month+1, 0);
// #5 affiche le mois
for(i=1; i<=d.getDate(); i++){
nb++;
if(nb>7){
// #6 si 7 cellules sont affichés, on passe à la ligne suivante
nb = 1;
h += '</tr><tr>';
}
// #7 affiche la cellule du jour
h += '<td class="'+(i==today ? me.classSelection:me.classTd)+'"><a href="#"'+(me.funcDateClic!='' ? ' onclick="+me.funcDateClic+'(\''+i+'/'+(month+1)+'/'+year+'\', \''+me.id+'\');return false;"':'')+'>'+i+'</a></td>';
}
// #8 affiche les dernières cellule pour terminer le tableau
for(i=nb; i<7; i++){
h += '<td> </td>';
}
h += '</tr></table>';
// #9 affiche le tableau
document.getElementById(me.id).innerHTML = h
}
La fonction show() permet d'afficher le calendrier. Elle commence par vérifier si le jour sélectionné (dateSel) peut être affiché (#1).
Elle affiche ensuite la ligne d'entête du tableau qui contient les noms des jours, enregistrés dans dayName (#2). Elle prépare l'affichage du premier jour du mois (#3). Le premier jour du mois doit être décalé en fonction de sa position dans le String dayOrder.
Il faut ensuite afficher les jours du mois en créant une boucle entre 1 et le dernier jour du mois.
Pour connaître le dernier jour du mois M (#4), il suffit de créer une date avec le mois suivant (M+1) et le jour 0.
Par exemple pour connaître le nombre de jour de Février 2014 :
var d = Date(2014, 3, 0); alert(d.getDate());
La fonction affiche chaque jour du mois (#5) et incrémente un compteur. Quand ce compteur atteint 7 (le nombre de jour de la semaine), une nouvelle ligne du tableau est crée (#6). jsSimpleDatePickr ne créer pas de date inutile à chaque boucle.
La cellule qui contient le jour est affiché et une class CSS y est attribué (#7) :
- classSelection est la class pour le jour sélectionné
- classTd est la class par défaut pour les jours du mois.
Le tableau est presque prêt, il suffit de finaliser la dernière ligne en affichant les cellules manquantes (#8).
Le tableau est prêt et sera affiché dans l'élément HTML qui a été passé en paramètre (#9).
Récapitulatif du code jsSimpleDatePickr
/*http://blog.niap3d.com/jsSimpleDatePickr*/
function jsSimpleDatePickr(id){
var me = this;
me.dateDisp = new Date();
me.dateSel = new Date();
me.dayOrder = '1234560';
me.dayName = ['D', 'L', 'M', 'M', 'J', 'V', 'S'];
me.id = id;
me.funcDateClic = me.classTable = me.classTd = me.classSelection = '';
me.setDate = function(dateStr){
if(!dateStr) return 0;
var dateArr = dateStr.split('/');
if(isNaN(dateArr[0])) return 0;
today = new Date();
if(isNaN(dateArr[1])) dateArr[1] = today.getMonth();
else dateArr[1] = parseInt(dateArr[1], 10)-1;
if(isNaN(dateArr[2])) dateArr[2] = today.getFullYear();
else if(parseInt(dateArr[2], 10)<100) dateArr[2] = parseInt(dateArr[2], 10)+2000;
me.dateSel = new Date(dateArr[2], dateArr[1], dateArr[0]);
me.dateDisp = new Date(dateArr[2], dateArr[1], dateArr[0]);
}
me.setMonth = function(val){
var v = parseInt(val, 10);
if(val.charAt(0)=='+' || val.charAt(0)=='-') v = me.dateDisp.getMonth()+v;
me.dateDisp.setMonth(v);
}
me.setYear = function(val){
var v = parseInt(val, 10);
if(val.charAt(0)=='+' || val.charAt(0)=='-') v = me.dateDisp.getFullYear()+v;
me.dateDisp.setFullYear(v);
}
me.show = function(){
var nb = today = 0;
var month = me.dateDisp.getMonth();
var year = me.dateDisp.getFullYear();
if(month==me.dateSel.getMonth() && year==me.dateDisp.getFullYear()) today = me.dateDisp.getDate();
var h = '<table class="'+me.classTable+'"><tr>';
for(var i in me.dayOrder){
h += '<th>'+me.dayName[me.dayOrder[i]]+'</th>';
}
h += '</tr><tr>';
var d = new Date(year, month, 1);
for(nb=0; nb<me.dayOrder.indexOf(d.getDay()); nb++){
h += '<td> </td>';
}
d.setMonth(month+1, 0);
for(i=1; i<=d.getDate(); i++){
nb++;
if(nb>7){
nb = 1;
h += '</tr><tr>';
}
h += '<td class="'+(i==today ? me.classSelection:me.classTd)+'"><a href="#"'+(me.funcDateClic!='' ? ' onclick="'+me.funcDateClic+'(\''+i+'/'+(month+1)+'/'+year+'\', \''+me.id+'\');return false;"':'')+'>'+i+'</a></td>';
}
for(i=nb; i<7; i++){
h += '<td> </td>';
}
h += '</tr></table>';
document.getElementById(me.id).innerHTML = h
}
}
Afficher / télécharger jsSimpleDatePickr.js
Conditions d'utilisations
Ce code est :
- Gratuit (oui, gratos, 0 euros HT)
- Libre d'utilisation pour vos projets privés et commerciaux
À condition de respecter les points suivants :
- Laisser l'adresse du blog dans le fichier jsSimpleDatePickr.js
- Si vous apportez des améliorations, merci de m'en faire part
- C'est tout !
Comment utiliser jsSimpleDatePickr ?
Lire la partie 2 de cette article sur l'utilisation du calendrier jsSimpleDatePickr avec exemple et code Javascript documenté.