Ajax Calendar - Modulo Calendario in XML + Javascript
Quello che vedete sulla destra di questo sito è un calendario particolare, nel senso che è progettato per il funzionamento asincrono tramite ajax. In questa maniera si può facilmente integrare un modulo calendario in qualsiasi sito con pochissime modifiche e separando nettamente la parte "intelligente" del programma, cioè la creazione dei giorni a partire da un dato mese/anno, dalla parte "meno intelligente", quella di output verso il browser.
Ecco quindi spiegato il funzionamento, separato in:
- Script PHP Server-Side che crea l'xml con i dati del mese/anno
- Script client-side in Javascript per iniettare il markup del calendario verso il browser
- Un esempio di markup HTML per rendere funzionante il tutto
Codice PHP server-side (Creazione dell'xml della coppia mese/anno richiesta)
<?php
$mese = $_GET['month'];
$anno = $_GET['year'];
$primoGiornoMese = date( "w", mktime (0, 0, 0, $mese, 1, $anno) );
if( $primoGiornoMese != 1 ) {
if( $primoGiornoMese == 0 ) $counter = 6;
else $counter = $primoGiornoMese - 1;
if( $mese == 1 ) { $vecchioMese = 12; $vecchioAnno = $anno - 1; } else { $vecchioMese = $mese -1; $vecchioAnno = $anno; }
$giorniMesePrecedente = date( "t", mktime(0, 0, 0, $vecchioMese, 1, $vecchioAnno) );
for($i = $counter - 1; $i >= 0; $i--) {
$curr = mktime(0, 0, 0, $vecchioMese, $giorniMesePrecedente - $i, $vecchioAnno);
$tArr = Array('mod' => 'oldmonth', 'day' => $giorniMesePrecedente - $i, 'changeRow' => false);
$calendario[] = $tArr;
}
}
$curr = mktime(0, 0, 0, $mese, 1, $anno);
$continua = true;
$k = 0;
while( $continua ) {
$flagStile = $cambiaRiga = false;
$giornoCorrente = date( "w", $curr );
$numeroCorrente = date( "d", $curr );
if( $curr == mktime(0, 0, 0, date("m"), date("d"), date("Y")) ) $flagStile = 'currentDay';
else {
if( $giornoCorrente != 6 && $giornoCorrente != 0 ) $flagStile = 'normalDay';
else $flagStile = 'weekendDay';
}
if( $giornoCorrente == 0 ) $cambiaRiga = true;
$tArr = Array('mod' => $flagStile, 'day' => $numeroCorrente, 'changeRow' => $cambiaRiga);
$calendario[] = $tArr;
$curr = mktime(0, 0, 0, $mese, date("d", $curr) + 1, $anno);
if( date("m", $curr) > $mese || ( date("m", $curr) == 1 && $mese == 12 ) || $k >= 50) $continua = false;
$k++;
}
$giorniCodestoMese = date("t", mktime(0, 0, 0, $mese, 1, $anno));
if( ( $giornoFinaleMese = date("w", mktime(0, 0, 0, $mese, $giorniCodestoMese, $anno)) ) != 0 ) {
for($i = 1; $i <= (7 - $giornoFinaleMese); $i++) {
$tArr = Array('mod' => 'oldmonth', 'day' => $i);
$calendario[] = $tArr;
}
}
header('Content-Type:text/xml');
echo '<?xml version="1.0" encoding="UTF-8" ?>' . chr(10);
echo '<root>' . chr(10);
echo '<monthInfo><month>' . substr( ucfirst(itdate("F", mktime(0, 0, 0, $mese, 1, $anno))), 0, 3 ) . '</month><year>' . $anno . '</year></monthInfo>' . chr(10);
foreach( $calendario as $giorno => $valoriGiorno ) {
$mod = $valoriGiorno['mod'];
$day = number_format($valoriGiorno['day'], 0, "", "");
$alt = $valoriGiorno['alt'];
$title = $valoriGiorno['title'];
$link = $valoriGiorno['link'];
$changeRow = ( $valoriGiorno['changeRow'] == false ) ? 0 : 1;
echo '<giorno mod="' . $valoriGiorno['mod'] . '" day="' . number_format($valoriGiorno['day'], 0, "", "") . '" changeRow="' . $changeRow . '"></giorno>' . chr(10);
}
echo '</root>' . chr(10);
function itdate ($date_format="l j F Y - H:i:s", $time=0) {//, $date_format="l j F Y - H:i:s", $lang=it
$hourdiff = "0";
$timeadjust = ($hourdiff * 60 * 60);
if (! $time) $time = time()+$timeadjust;
if (! $lang) $lang = "It";
if (! $date_format)
{
$date_format = "l j F Y - H:i:s";
}
$week_days_long = array('Sunday' => 'Domenica', 'Monday' => 'Lunedì ', 'Tuesday' => 'Martedì',
'Wednesday' => 'Mercoledì', 'Thursday' => 'Giovedì', 'Friday' => 'Venerdì',
'Saturday' => 'Sabato');
$months_long = array('January' => 'Gennaio', 'February' => 'Febbraio',
'March' => 'Marzo', 'April' => 'Aprile','May' => 'Maggio', 'June' => 'Giugno',
'July' => 'Luglio', 'August' => 'Agosto', 'September' => 'Settembre',
'October' => 'Ottobre', 'November' => 'Novembre', 'December' => 'Dicembre');
$week_days_short = array('Sun' => 'Dom', 'Mon' => 'Lun', 'Tue' => 'Mar', 'Wed'=>'Mer',
'Thu' => 'Gio', 'Fri' => 'Ven', 'Sat' => 'Sab');
$months_short = array('Jan' => 'Gen', 'Feb' => 'Feb', 'Mar' => 'Mar', 'Apr' => 'Apr',
'May' => 'Mag', 'Jun' => 'Giu', 'Jul' => 'Lug', 'Aug' => 'Ago',
'Sep' => 'Set', 'Oct' => 'Ott', 'Nov' => 'Nov', 'Dec' => 'Dic');
$clock = date($date_format, $time);
if(preg_match("/F/", $date_format) && ($lang != "En")) {
$model = date("F", $time);
$replace = $months_long[date("F", $time)];
$clock = preg_replace("/$model/", $replace, $clock);
}
if(preg_match("/l/", $date_format) && ($lang != "En")) {
$model = date("l", $time);
$replace = $week_days_long[date("l", $time)];
$clock = preg_replace("/$model/", $replace, $clock);
}
if(preg_match("/M/", $date_format) && ($lang != "En")) {
$model = date("M", $time);
$replace = $months_short[date("M", $time)];
$clock = preg_replace("/$model/", $replace, $clock);
}
if(preg_match("/D/", $date_format) && ($lang != "En")) {
$model = date("D", $time);
$replace = $week_days_short[date("D", $time)];
$clock = preg_replace("/$model/", $replace, $clock);
}
return strtolower($clock);
}
?>Codice Javascript per l'iniettamento del markup del calendario verso il browser
/* Calendar Handler JS client-side script v1.1 */
/*
CONFIGURAZIONE:
Cambiare i valori delle variabili di configurazione, sapendo che:
_id_contenitore_calendario = ID del contenitore che andrà a contenere il calendario. E' un div che conterrà solo una tabella. SPECIFICARE IL # prima dell'id.
_id_contenitore_header_mese_anno = ID del contenitore che conterrà la coppia mese-anno sopra la tabella del mese.
_classe_cella_mesenoncorrente = classe css da applicare alle celle che NON sono del mese corrente, ma che mandiamo in output per completezza
_classe_cella_mesecorrente = classe css da applicare alle celle che sono del mese corrente
_classe_cella_weekend = classe css da applicare alle celle che sono sabato o domenica del mese corrente
_classe_cella_giornocorrente = classe css da applicare nel caso in cui una cella-giorno del calendario corrisponda al giorno corrente
ESEMPIO MARKUP HTML PER RENDERE FUNZIONANTE IL MODULO CALENDARIO:
<div id="contenitore_tabella_calendario">
<p id="header_tabella_calendario"></p>
<table>
<tbody></tbody>
</table>
</div>
*/
// Inizializzazione variabili
_id_contenitore_calendario = '#contenitore_tabella_calendario';
_id_contenitore_header_mese_anno = '#header_tabella_calendario';
_classe_cella_mesenoncorrente = 'oldmonth';
_classe_cella_mesecorrente = 'normalmonth';
_classe_cella_weekend = 'weekendday';
_classe_cella_giornocorrente = 'currentday';
//Gestione Data Odierna
var today = new Date();
var mese = today.getMonth() + 1;
var anno = today.getFullYear();
// Trigger delle funzioni da far partire all'avvio
$(document).ready(function() {
$.ajax({
type: "GET",
url: "xml_calendar_creator.php",
data: "month=" + mese + "&year=" + anno,
dataType: 'xml',
success: parseXmlCalendario,
error: function (a, b, e) {
throw(e);
}
});
});
parseXmlCalendario = function(xml) {
// Variabile della classe delle celle per la tabella del calendario
var cellClass = "";
// Iniettamento del titolo del calendario (Mese e Anno)
$(_id_contenitore_header_mese_anno).html( $(xml).find('monthInfo month').text() + " " + $(xml).find('monthInfo year').text());
// Iniettamento del codice html completo per il calendario
var htmlCalendario = '<tr>';
$(xml).find('giorno').each(function() {
var mod = $(this).attr('mod');
var giorno = $(this).attr('day');
var cambiaRiga = $(this).attr('changeRow');
switch ( mod ) {
case 'oldmonth':
cellClass = _classe_cella_mesenoncorrente;
break;
case 'normalDay':
cellClass = _classe_cella_mesecorrente;
break;
case 'currentDay':
cellClass = _classe_cella_giornocorrente;
break;
case 'weekendDay':
cellClass = _classe_cella_weekend;
break;
default: break;
}
htmlCalendario += '<td class="' + cellClass + '" align="center">' + giorno + '</td>';
if ( cambiaRiga == 1 ) htmlCalendario += '</tr><tr>';
});
htmlCalendario += '</tr>';
$(_id_contenitore_calendario + ' tbody').html(htmlCalendario);
}Esempio di markup HTML per rendere il tutto funzionante
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Prova</title>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="calendar_js.js"></script>
</head>
<body>
<div id="contenitore_tabella_calendario">
<p id="header_tabella_calendario"></p>
<table>
<tbody></tbody>
</table>
</div>
</body>
</html>Mischiare il tutto
Il codice PHP può essere salvato con un nome qualsiasi, solo bisogna ricordarsi di andare a modificare il file javascript e, sotto la parte di creazione della richiesta ajax, andare a modificare il nome della variabile che contiene le impostazioni della richiesta.
Ricordo che questo sistema implica forzatamente l'utilizzo della libreria jQuery per poter funzionare. È chiaramente visibile nel terzo snippet di codice HTML, dove è specificato il richiamo del file jquery.js




