Měsíční kalendář pomocí JavaScriptu

19. září 2001

Tu a tam je zapotřebí vyrobit do HTML stránky tabulku s rozvržením dnů v týdnu v aktuálním měsíci – ať již při aplikaci typu kalendáře, na stránce hotelu s rezervací termínu pobytu či jinde. Tento úkol je jak dělaný pro skript. V následujícím článku si ukážeme výrobu měsíčního kalendáře na klientské straně – pomocí JavaScriptu.

Kalendář pro aktuální měsíc vykreslený JavaScriptem může vypadat například takto (aktuální datum je vyznačeno červeně):

Vykreslování zajišťuje poněkud delší funkce, zde nazvaná WriteMonthTable. Než se do ní pustíme, nejprve trochu dělostřelecké přípravy – hrst pomocných funkcí a proměnných, které zajistí podporu funkci hlavní. Jako první jsou na řadě dvě pomocná pole, do nichž uložíme názvy měsíců a dnů v týdnu:

var monthNames=new Array("Leden","Únor","Březen","Duben",
        "Květen","Červen","Červenec","Srpen",
        "Září","Říjen","Listopad","Prosinec");
var dayNames=new Array("Pondělí","Úterý","Středa",
        "Čtvrtek","Pátek","Sobota","Neděle");

Následuje pomocná funkce WriteCell, jež vykreslí buňku tabulky (tedy vlastně jedno políčko kalendáře) zadanou barvou a s číslem dne uvnitř. Ternální operátor uvniř zajišťuje vykreslení prázdného obsahu v případě, že je jako den zadáno číslo nula – tedy pro doplňující šedá políčka tabulky. Tato funkce bude pravděpodobně nejvíce upravována v závislosti na konkrétní aplikaci:

function WriteCell( bgColor, day ) {
    document.write("<td bgcolor=’" + bgColor +
        "‘ align=’right‘ valign=’top‘><font size=’2′><b>" +
        (day!=0?day:"&nbsp;") +
        "</b></font></td>");
}

Funkce IsToday vrací bool hodnotu, zda datum zadané jako trojice jejich parametrů odpovídá dněšnímu datu. Funkce je využívána pro vykreslení červeného podkladu pod pole tabulky s aktuálním datem:

function IsToday( d, m, y ) {
var myDate= new Date();
    if (     (myDate.getDate()==d) &&
        (myDate.getMonth() == m) &&
        (myDate.getFullYear() == y) )     {
        return true
    }
    return false
}

Tolik funkce pomocné, nyní k hlavní funkci skriptu s názvem WriteMonthTable. Jak název napovídá, její prací je vykreslit celou tabulku měsíčního kalendáře. Dvěma parametry na jejím vstupu jsou čísla měsíce a roku, který je třeba kreslit. Funkce není složitá, je však dlouhá – pro přehlednost si ji tedy uvedeme po částech. Nejprve hlavička funkce a deklarace lokálních proměnných:

function WriteMonthTable(the_month,the_year) {
var cellColor
var day_counter=1;
var first_day= new Date(the_year,the_month,1);
first_day=first_day.getDay();
first_day=first_day==0?6:first_day-1
var day_in_month=31;
if (the_month == 3 || the_month == 5 || the_month == 8 || the_month == 10) {
    day_in_month=30;
}
if (the_month == 1) {
    day_in_month=28;
    if ( ((the_year % 4 == 0) && (the_year % 100 != 0)) || (the_year % 400 == 0) ) {
        day_in_month=29;
    }   
}

Do proměnné first_day ukládáme pořadové číslo prvního dne měsíce v rámci týdne (s převodem z amerického způsobu číslování s nedělí jako prvním dnem týdne na náš), proměnná day_in_month ukazuje počet dnů v měsíci (její poněkud komplikované nastavování je způsobeno nutností zohlednit přestupné roky). Následuje výpis záhlaví tabulky s názvem aktuálního měsíce (a roku) a názvy jednotlivých dnů týdne:

document.write("<table bgcolor=’white‘ border=’1′ width=’300′ cellpadding=’3′ cellspacing=’1′>");
document.write("<tr height=’20‘><td bgcolor=’gray‘ align=’left‘ colspan=’7′><font size=’3′ color=’black‘><b>" + monthNames[the_month] + " " + the_year + "</b></font></td></tr>");
document.write("<tr height=’20‘>");
for( var i=0; i<7; i++ ) {
    document.write("<td bgcolor=’gray‘><font color=’black‘ size=’2′>"
        + dayNames[i] + "</font></td>");
}
document.write("</tr>")

První řádek tabulky vypisujeme nadvakrát, nejprve šedá políčka a poté první (většinou necelou) část týdne. Pomocná proměnná day_counter určuje pořadové číslo dne, právě vypisovaného:

document.write("<tr height=’50‘>");
for (i=0;i<(first_day);i++) {
    WriteCell("gray",0)
}
for (i=first_day;i<7;i++) {
    cellColor = IsToday(day_counter,the_month,the_year) ? "red" : "white"
    WriteCell(cellColor,day_counter)
    day_counter=day_counter + 1;
}
document.write("</tr>");

Zbylé řádky tabulky už můžeme vypsat najednou pomocí dvou zanořených smyček. Jediné, co je potřeba hlídat, je dosažení posledního dne v měsíci a ukončení smyček – to je realizováno nastavením řídících proměnných obou cyklů a a b v příslušné podmínce (což není pravda zrovna vrchol estetiky, přesto je to o cosi civilizovanější než basicovská nemorálnost jménem GOTO). Za tímto úsekem kódu je uvedena jedna pravá složená závorka navíc jako ukončení celé funkce WriteMonthTable:

for (a=1;a<6;a++) {
    document.write("<tr height=’50‘>");
    for (b=0;b<7;b++) {
        cellColor = IsToday(day_counter,the_month,the_year) ? "red" : "white"
        WriteCell(cellColor,day_counter)
        if (day_counter >= day_in_month){
            for (i=b;i<6;i++) {
                WriteCell("gray",0)
            }
            b=7; a=5;
        }
        day_counter=day_counter + 1;
    }
    document.write("</tr>");   
}
document.write("</table>");
}

Zbývá funkci ve vhodném místě HTML stránky zavolat; jak je zřejmé z parametrů, lze vykreslovat nejen tabulku pro aktuální měsíc, ale i pro další měsíce libovolného roku (tedy s jistými omezeními – skript sice nezhavaroval na roku 85 před naším letopočtem, dny v týdnu však díky gregoriánské reformě zřejmě nesouhlasí). Takže zde je volání pro vykreslení aktuálního měsíce v aktuálním roce:

var pomDate= new Date();
WriteMonthTable( pomDate.getMonth(),pomDate.getFullYear() );

A to je pro tentokrát vše. Jak vidno, jedná se o holou kostru kalendáře, určenou k „dovybavení“ obsahem a funkcemi dle konkrétní aplikace – formulářovými políčky, výpisem obsahu jednotlivých dnů atd atd. Příště si ukážeme jednu z možných aplikací – propojení s kalendářem událostí či výročí.

Přeji vám příjemný den.

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *