Micro-calendar

Soyez le premier à donner votre avis sur cette source.

Vue 19 587 fois - Téléchargée 1 833 fois

Description

affiche un calendrier sous une zone de saisie
version 4.2 de mon calendrier
        • listes des paramètres du calendrier :


mois : tableau contenant la liste des libellées des mois
type : new Array()
valeur par défaut :
new Array("Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Aout", "Septembre", "Octobre", "Novembre", "Décembre")

jour : tableau contenant la liste des libellées des jours (version courte)
type : new Array()
valeur par défaut : new Array("Di","Lu","Ma","Me","Je","Ve","Sa")

jLib : tableau contenant la liste des libellées des jours (version longue)
type : new Array()
valeur par défaut : new Array("Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi")

titre : titre du calendrier affiché en entête, si valeur = "" alors n'affiche pas le titre
type : String
valeur par défaut : "micro-calendar"

aujourdhui : libellé affiché en bas correspondant au raccourci de la date du jour,
type : String
valeur par défaut : "aujourd'hui"

debutSemaine : index correspondant au 1er jour de la semaine, 0=dim,1=lun,2=mar,3=mer,4=jeu,5=ven,6=sam
type : int
valeur par défaut : 1

jPause : tableau avec les index des jours correspondant aux jours des week-end, la clef et l'index du jour la valeur = true
type: Map
valeur par défaut : {6:true,0:true} correspond à (samedi & dimanche)

jFeriee: tableau avec la liste des jours fériées, la clef correspond à "jj-mm" (jour-mois) et la valeur le libellé du jour férié
type : Map
valeur par défaut :
{"1-1":"jour an", "1-5":"fête du travail", "8-5":"armistice", "14-7":"fête nationale", "15-8":"ascencion", "1-11":"armistice", "11-11":"toussain", "25-12":"noel"}

moisMoins : libellé affiché pour la navigation du mois précédent
type : String
valeur par défaut : "-"

moisPlus : libellé affiché pour la navigation du mois suivant
type : String
valeur par défaut : "+"

anneeMoins : libellé affiché pour la navigation de l'année précédent
type : String
valeur par défaut : "<"

anneePlus : libellé affiché pour la navigation de l'année suivant
type : String
valeur par défaut : ">"

format: format de la date de sortie les caractère %j,%m,%a,... seront remplacer par leurs valeurs en fonction des correspondance
%j : retourne le jour avec zero devant si <10
%k : retourne le jour
%d : retourne le libellé du jour : Lundi, Mardi, Mercredi,Jeudi,Vendredi, Samedi, Dimanche
%m : retourne le mois avec zero devant si <10
%n : retourne le mois
%p : retourne le libellé du mois : Janvier, Fervrier, Mars, Avril, Mai, Juin, Juillet, Aout, Septembre, Octobre, Novembre, Decembre
%a : retourne l'année sur 4 positions
%y : retourne l'année sur 2 positions
type : String
valeur par défaut : "%j/%m/%a" correspondant à jour/mois/année

date : utiliser en interne, remplacer par la date sélectionnée (utiliser avec les calendriers liés)
type : Date
valeur par défaut : null

ddeb : identifiant du calendrier de la date de début (correspond à l'id de l'input)
type : String
valeur par défaut : ""

dfin : identifiant du calendrier de la date de fin(correspond à l'id de l'input)
type : String
valeur par défaut : ""

dateMin : date minimum du calendrier, ex: si dateMin = new Date(2009,0,1) alors on ne pourra pas sélectionner de date avant le 1er Janvier 2009
type : Date
valeur par défaut : null

dateMax : date maximum du calendrier, ex: si dateMax = new Date(2009,11,31) alors on ne pourra pas sélectionner de date apres le 31 décembre 2009
type : Date
valeur par défaut : null
        • listes des styles :

en fonction des jours, les styles sont emboités de la façon suivant :

<div class='divCal'>
<table>
<tr>
<td colspan='8' class='zoneTitre' >
[titre]
</td>
</tr>
<tr>
<td colspan='8'>
<table>
<tr>
<td class='zoneNav'> [<] </td>
<td class='zoneNav'> [-] </td>
<td class='zoneMois'> [mois] </td>
<td class='zoneNav'> [+] </td>
<td class='zoneNav'> [>] </td>
</tr>
</table>
</td>
</tr>
...
<tr>
<td class='nSemaine'>
[Sem]
</td>
...
<td>
<a class='tdx' href='#' onclick='...'>
<div class='enWeekEnd' > <-- présent si jour = week-end
<div class='enFeriee' title='...'> <-- présent si jour = fériée
<div class='enMois' > <-- présent si mois = mois en cours
<div class='aujourdhui'> <-- présent si jour = aujourd'hui
[Jour] <-- jour du mois
</div>
</div>
</div>
</div>
</a>
</td>
...
</tr>
<tr>
<td colspan='6'><a class='tdxNow' href='#' onclick='...'>[aujourdhui]</a></td>
<td colspan='2' class='zoneAnnee'>[annee]</td>
</tr>
</table>
</div>

Source / Exemple :


/****************

  • script MICRO-CAL (V4.2) par Amroune Selim (amrounix@gmail.com)
  • toutes copies, diffusions,modifications ou améliorations sont autorisées
                                • /
var pDefaut = { /*variable globale*/ "mois" : new Array("Janvier","Février","Mars","Avril","Mai","Juin","Juillet","Aout","Septembre","Octobre","Novembre","Décembre"), "jour" : new Array("Di","Lu","Ma","Me","Je","Ve","Sa"), "jLib" : new Array("Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"), "titre" : "micro-calendar", "aujourdhui" : "aujourd'hui", "debutSemaine" : 1, /*debut de la semaine 0=dim,1=lun,...*/ "jPause" : {6:true,0:true},/*jour de pause de la semaine (samedi & dimanche)*/ "jFeriee": {"1-1":"jour an","1-5":"fête du travail","8-5":"armistice","14-7":"fête nationale","15-8":"ascencion","1-11":"armistice","11-11":"toussain","25-12":"noel"} , "moisMoins" : "-", "moisPlus" : "+", /*naviagation par mois*/ "anneeMoins" : "<", "anneePlus" : ">", /*naviagation par annee*/ "format" : "%j/%m/%a", /*format de sortie : %j = jour, %m = mois, %a =année*/ "date" : null, "ddeb" : "", "dfin" : "", "dateMin" : null, "dateMax" : null } var tempo = new Array(); /*gestion de la fermeture des calendriers quand on perd le focus*/ var nomove={"TR":0,"CENTER":0,"B":0,"P":0,"U":0,"I":0,"DIV":0,"A":0,"FONT":0,"LI":0,"PRE":0,"SPAN":0,"SUB":0,"SUP":0,"FORM":0}; //var nomove={"TD":0,"TABLE":0}; function _(x) /*simplification des appels*/ {return document.getElementById(x);} function nbJ(dateX) /*Retourne le nombre de jour depuis le 1er janvier (pr le num de semaine)*/ { var j_mois=[0,31,59,90,120,151,181,212,243,273,304,334]; mm=dateX.getMonth();aa=dateX.getFullYear();nb=j_mois[mm]+dateX.getDate()-1 ; if ((aa%4==0 && aa %100!=0 || aa%400==0) && mm>1) nb++; /*test bissextile*/ return nb; } function dateMin(dateA,dateB) { return (dateB==null||(dateA!=null&&(dateA.getFullYear()<dateB.getFullYear() ||(dateA.getFullYear()==dateB.getFullYear()&&dateA.getMonth()<dateB.getMonth()) ||(dateA.getFullYear()==dateB.getFullYear()&&dateA.getMonth()==dateB.getMonth()&&dateA.getDate()<dateB.getDate()) ))) ? dateA:dateB } function dateMax(dateA,dateB) { return (dateB==null||(dateA!=null&&(dateA.getFullYear()>dateB.getFullYear() ||(dateA.getFullYear()==dateB.getFullYear()&&dateA.getMonth()>dateB.getMonth()) ||(dateA.getFullYear()==dateB.getFullYear()&&dateA.getMonth()==dateB.getMonth()&&dateA.getDate()>dateB.getDate()) ))) ? dateA:dateB } function dateBefore(dateA,dateB) /*compare 2 date et retourne true si dateA<=dateB*/ { return dateA!=null&&dateB!=null&&(dateA.getFullYear()<dateB.getFullYear()||(dateA.getFullYear()==dateB.getFullYear()&&dateA.getMonth()<dateB.getMonth())|| (dateA.getFullYear()==dateB.getFullYear()&&dateA.getMonth()==dateB.getMonth()&&dateA.getDate()<dateB.getDate())); } function htmNavChk(dateA,dateB,src,srcId,mm,yy,txt) /*methode pour afficher les infos de navigation*/ { return (dateBefore(dateA,dateB)) ? "<td onclick=\"\">&nbsp;</td>" : ("<td class='zoneNav' onclick=\"return gCal('"+src+"','"+srcId+"',"+mm+","+yy+")\">"+txt+"</td>"); } function gCal(src,srcId,mm,yy) /*génère le calendrier*/ { if (tempo!=null&&tempo[srcId]!=null) { clearTimeout(tempo[srcId]); _(src).focus(); } if (mm<0) {mm+=12;yy--;} /*changment de mois/année*/ else if (mm>11) {mm-=12;yy++;} dnow=new Date(); /*date du jour*/ param=_(srcId).parametre; /*parametre par defaut*/ ddeb = null; dfin = null; if (param["ddeb"]!="" && _(param["ddeb"]+"_cal")!=null && _(param["ddeb"]+"_cal").parametre.date != null) ddeb = _(param["ddeb"]+"_cal").parametre.date; if (param["dfin"]!="" && _(param["dfin"]+"_cal")!=null && _(param["dfin"]+"_cal").parametre.date != null) dfin = _(param["dfin"]+"_cal").parametre.date; htm="<table cellpadding=0 cellspacing=0 >"; /*titre*/ if (param["titre"]!= null ) {htm+="<tr><td colspan='8' class='zoneTitre' >"+param["titre"]+"</td></tr>";} /*zone de navigation*/ htm+="<tr><td colspan='8'><table width='100%' cellpadding=0 cellspacing=0 ><tr>"; htm+=htmNavChk(new Date(yy-1,mm,1),dateMax(ddeb,param["dateMin"]),src,srcId,mm,yy-1,param["anneeMoins"]); htm+=htmNavChk(new Date(yy,mm,0),dateMax(ddeb,param["dateMin"]),src,srcId,mm-1,yy,param["moisMoins"]); htm+="<td class='zoneMois'>"+param["mois"][mm]+"</td>"; htm+=htmNavChk(dateMin(dfin,param["dateMax"]),new Date(yy,mm+1,1),src,srcId,mm+1,yy,param["moisPlus"]); htm+=htmNavChk(dateMin(dfin,param["dateMax"]),new Date(yy+1,mm,1),src,srcId,mm,yy+1,param["anneePlus"]); htm+="</tr></table></td></tr>"; /*jours de la semaine*/ htm+="<tr><td></td>"; pJs = param["debutSemaine"]; pJm = new Date(yy,mm,1).getDay(); /*jour du 1ere du mois*/ pjT = 1-pJm+pJs; pjT-=(pjT>1)?7:0; dateX = new Date(yy,mm,pjT); for (j=0;j<7;j++) /*affiche les jours de la semaine*/ {htm+="<td>"+param["jour"][(j+pJs)%7]+"</td>";} htm+="</tr>"; avantFinMois=true;idx=0; idxSem=parseInt(nbJ(new Date(yy,mm,1))/7+1,10); /*index de la semaine*/ while(avantFinMois) /*boucle jusqu'a la fin du mois */ { htm+=(idx%7==0)?"<tr><td class='nSemaine' >"+idxSem+"</td>":""; /*affiche le numero de semaine*/ if (dateBefore(dateX,dateMax(ddeb,param["dateMin"]))||dateBefore(dateMin(dfin,param["dateMax"]),dateX)) htm+="<td style='text-decoration:line-through;'><a class='tdx' href='#'>"+subDiv(param,idx,dateX,mm,aa,0)+"</b></td>"; else htm+="<td><a class='tdx' href='#' onclick=\"javascript:choix("+dateX.getFullYear()+","+dateX.getMonth()+","+dateX.getDate()+",'"+srcId+"','"+src+"')\" >"+subDiv(param,idx,dateX,mm,aa,0)+"</a></td>"; idx++; if (idx%7==0) {htm+="</tr>"; idxSem++;} dateX= new Date(dateX.getFullYear(),dateX.getMonth(),dateX.getDate()+1); if (idx>7&&idx%7==0&&dateX.getMonth()!=mm) {avantFinMois=false;} } htm+="<tr><td colspan='6'>&nbsp;&nbsp;"; if (!dateBefore(dnow,dateMax(ddeb,param["dateMin"]))&&!dateBefore(dateMin(dfin,param["dateMax"]),dnow)) htm+="<a class='tdxNow' href='#' onclick=\"javascript:choix("+dnow.getFullYear()+","+dnow.getMonth()+","+dnow.getDate()+",'"+srcId+"','"+src+"')\" >"+param["aujourdhui"]+"</a>"; else htm+="&nbsp;" /*annee*/ htm+="</td><td colspan='2' class='zoneAnnee'>"+yy+"</td></tr></table>"; //alert(htm); _(srcId).innerHTML=htm; return false; } function addZero(val) /*ajoute un zero devant*/ { return ((val<10)?"0":"")+val;} function choix(aa,mm,jj,srcId,src) { var datePos=new Date(aa,mm,jj); var jour = datePos.getDay(); param=_(srcId).parametre; param.date = datePos; var dateAffiche = param["format"].replace("%j",addZero(datePos.getDate())).replace("%k",datePos.getDate()).replace("%d",param["jLib"][jour]); dateAffiche = dateAffiche.replace("%m",addZero(datePos.getMonth()+1)).replace("%n",datePos.getMonth()+1).replace("%p",param["mois"][datePos.getMonth()]); dateAffiche = dateAffiche.replace("%a",datePos.getFullYear()).replace("%y",datePos.getYear()); _(src).value = dateAffiche; } function subDiv(param,idx,dateX,mm,aa,code) { pJs = param["debutSemaine"]; dnow=new Date(); switch(code) { case 0 : return (param["jPause"][(idx+pJs)%7]==true) ? "<div class='enWeekEnd' >"+subDiv(param,idx,dateX,mm,aa,1)+"</div>" : subDiv(param,idx,dateX,mm,aa,1) ; break; case 1 : return (param["jFeriee"][dateX.getDate()+"-"+(dateX.getMonth()+1)]!=null) ? ("<div class=\"enFeriee\" title=\""+param["jFeriee"][dateX.getDate()+"-"+(dateX.getMonth()+1)]+"\" >"+subDiv(param,idx,dateX,mm,aa,2)+"</div>") : subDiv(param,idx,dateX,mm,aa,2) ; break; case 2 : return (dateX.getMonth()==mm) ? "<div class='enMois' >"+subDiv(param,idx,dateX,mm,aa,3)+"</div>" : subDiv(param,idx,dateX,mm,aa,3) ; break; case 3 : return (dateX.getMonth()==dnow.getMonth()&&dateX.getFullYear()==dnow.getFullYear()&&dateX.getDate()==dnow.getDate()) ? "<div class='aujourdhui' >"+subDiv(param,idx,dateX,mm,aa,4)+"</div>" : subDiv(param,idx,dateX,mm,aa,4) ; break; case 4 : return dateX.getDate(); break; } } function getMinx(tab,mini) { var rc=mini,code=""; for (k in tab) { if (tab[k]>mini && rc<tab[k]) {rc=tab[k]; code = k; } } return code; } function decodeDate(val,format,defaut) { var dnow = defaut,jj= dnow.getDate(),mm = dnow.getMonth(), aa= dnow.getFullYear(); var parx = {"%j":"([0123][0-9])","%k":"([0123]?[0-9])","%d":"("+(param["jLib"].join("|"))+")","%m":"([01][0-9])","%n":"([01]?[0-9])", "%p":"("+(param["mois"].join("|"))+")","%a":"([12][0-9]{3})","%y":"([0-9]{2})"}; var ff= format,df = format; for (e in parx) { ff = ff.replace(e,parx[e]); df = df.replace(e,"("+e+")"); } tablo = (new RegExp(ff)).exec(val); clef = (new RegExp(df)).exec(format); if (tablo!=null&&clef!=null) { for (i = 0; i< tablo.length;i++) { switch(clef[i]) { case "%j": case "%k" : jj=parseInt(tablo[i],10); break; case "%m": case "%n" : mm=parseInt(tablo[i],10)-1; break; case "%p" : mm=0; while(mm<param["mois"].length&&param["mois"][mm]!=tablo[i]){mm++;}; break; case "%a": aa = parseInt(tablo[i],10); break; } } } return new Date(aa,mm,jj); } function visuCal(src,paramX) { if (src.id=="") /*si il n'y pas d'ID on en créé un*/ { cpt=0; while(_("microcal"+cpt) != null) {cpt++;} src.id="microcal"+cpt; } pos_= posxy(src,0,src.offsetHeight ); srcId = src.id+"_cal"; /*id du div du calendrier*/ dnow= new Date(); if (_(srcId)==null) /*si il existe pas on le créé*/ { param={} for (e in pDefaut) { trouve=false; if (paramX!=null) for (i in paramX) { if (e==i) {param[e]=paramX[e];trouve=true;} } if (!trouve) param[e]=pDefaut[e]; } dnow = decodeDate(src.value,param.format,new Date()); div = document.createElement('div'); div.setAttribute('id',srcId); div.style.position = 'absolute'; div.style.top = pos_.y + 'px'; div.style.left = pos_.x + 'px'; /*this.deltaG = 0; */ div.className = 'divCal'; div.parametre = param; document.body.appendChild(div); gCal(src.id,srcId,dnow.getMonth(),dnow.getFullYear(),param); } else { div = _(src.id+"_cal"); div.style.display='inline';/*affiche le calendrier*/ div.style.top = pos_.y + 'px'; div.style.left = pos_.x + 'px'; /*this.deltaG = 0; */ } } function masqueCal(src) {tempo[src.id+"_cal"]=window.setTimeout("_('"+src.id+"_cal').style.display='none'",500);} /*retourne la position en {x,y} d'un element */ function posxy(rst,x,y) { if ( rst.style!=null && rst.style.position == 'absolute' ) { return {"x":x + rst.offsetLeft,"y":y + rst.offsetTop} } else if (rst.parentNode == null ) { return {"x":x,"y":y} } else { return (nomove[rst.tagName]==0) ? posxy(rst.parentNode,x,y) : posxy(rst.parentNode,x+rst.offsetLeft,y+rst.offsetTop) ; } }

Conclusion :


séparation des fichiers + ajout d'exemples

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
3
Date d'inscription
lundi 7 avril 2008
Statut
Membre
Dernière intervention
10 août 2009

Merci pour la réponse. J'ai pas essayé ta fonction posxy(), je ne connais rien au javascript donc je te fais confiance. La mienne est sûrement plus bordélique, j'ai adapté une fonction trouvée sur google à ton code. Mais elle semble équivalente.

Petite correction pour ta réponse au niveau de la semaine.
Si on écris cette ligne : htm+=(idx%7==0)?"<tr>":""; /*affiche le numero de semaine*/
Les n° jours se décalent vers la gauche mais pas les noms de jours (Lu, Ma, ...)
J'ai préféré écrire : htm+=(idx%7==0)?"<tr><td class='nSemaine' >"+""+"</td>":"";
ça permet de supprimer toute la colonne à priori, pourquoi ? je ne sais pas trop. Bidouillage !

Merci encore pour ce calendrier, je l'ai adapté relativement vite au site web, et il fonctionne à merveille, tellement simple à prendre en main et paramétrer à son gout.
Messages postés
79
Date d'inscription
lundi 10 mars 2003
Statut
Membre
Dernière intervention
12 juillet 2010

HeLLo, alors si tu veux enlever le numéro de semaine remplace la ligne :
htm+=(idx%7==0)?"<tr><td class='nSemaine' >"+idxSem+"</td>":""; /*affiche le numero de semaine*/
par
htm+=(idx%7==0)?"<tr>":""; /*affiche le numero de semaine*/
et pour l'emplacement du calendrier, j'avais déjà trouvé une méthode pour corriger le repositionnement, il faut remplacer la méthode
function posxy(rst,x,y)
{...}
par
function posxy(rst,xx,yy) {
var cc = { x: xx, y: yy };
while (rst) {
cc.x += rst.offsetLeft;
cc.y += rst.offsetTop;
rst = rst.offsetParent;
}
return cc;
}

@+
Messages postés
3
Date d'inscription
lundi 7 avril 2008
Statut
Membre
Dernière intervention
10 août 2009

Solution trouvée !
Si cela arrive à d'autres que moi, voici une petite modification :
Remplacer : pos_= posxy(src,0,src.offsetHeight ); l.213
par
pos_ = new Array();
pos_ = getOffsets(_(src.id));

de même div.style.top = pos_.y + 'px'; l.229 et 238
par div.style.top = (pos_[1] + 18) + 'px';

et div.style.left = pos_.x + 'px'; l.230 et 239
par div.style.left = (pos_[0] + 18) + 'px';

puis supprimer entièrement la fonction :
function posxy

à remplacer par :
/* retourne la position en {x,y} d'un element sous forme de tableau */
function getOffsets(obj) {
var offsetTop = obj.offsetTop;
var offsetLeft = obj.offsetLeft;
while ((obj = obj.offsetParent )!=null) {
offsetTop += obj.offsetTop;
offsetLeft += obj.offsetLeft;
}
return [offsetLeft, offsetTop];
}
---------------------------
Le calendrier s'affichera avec une meilleure précision dans votre page malgré des div différentes et/ou superposées. Normalement, ... en tout cas pour moi. Après je ne suis pas sûr de ma syntaxe, je ne connais rien au javascript. ça marche par tatonnement.
dites moi pour le résultat que vous aurez.

Une question sinon :
comment enlever la colonne des numéros de semaines ?
Messages postés
3
Date d'inscription
lundi 7 avril 2008
Statut
Membre
Dernière intervention
10 août 2009

Pas assez de commentaire à mon goût.
J'essai d'intégrer ton code dans un site web; Un problème vient de m'apparaitre et tu sauras peut-être le résoudre.
l'affichage des calendriers est calculé par rapport à la position qu'auraient les input dans la div parent et non dans leur div effective. Je ne sais pas si c'est clair. Le calendrier ne prend pas en compte que les input puissent être dans une div décalées.
sinon je me trompe et pourrait tu m'expliquer comment rectifier cela ?

bien sinon, mais plus de commentaires serait génial (et un peu d'indentation) ;)
Messages postés
79
Date d'inscription
lundi 10 mars 2003
Statut
Membre
Dernière intervention
12 juillet 2010

HeLLo, j'ai mis en ligne la version 4.2 de mon calendrier, le calendrier sera positionné par défaut en fonction de la date dans la zone de saisie.
Il détecte tout type de date en fonction du format choisi ex :
"20 Décembre 1979" et que format vous avez mis "%j %p %a"
ou bien "1979-12-20" si vous avez mis "%a-%m-%j",...
Bref j'ai mis un truc hyper technique qui s'appelle : decodeDate() que personne ne verra jamais ... lol
Afficher les 26 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.