Popravdě nevím, kdy s tím budu hotov… Motivační emaily posílejte na mishak@mishak.net, jo a spam taky ;)

Kalendářík JavaScriptem se špetkou AJAXu

BUUFův kalendářTaky tak dlouho čekáte na pořádný článek o AJAXu? Buď se naučíte anglicky a zeptáte se strejdy Googla, nebo si ještě nějakou tu chvilku počkáte… Tento spot berte spíše jako představení mého AJAXového prototypu a pár dalších funkcí které mi v JavaScriptu ulehčují život.

Princip tohoto kalendáře je relativně jednoduchý: Načte se stránka calendar.init(), vygeneruje se kalendář calendar.dateCtrl(offset) a AJAXem se stáhnou data. Po stažení dat se dny kalendáře doplní odkazy calendar.parseMonth(xml). Pro nedočkavce líné napsat si vlastní kalendářík, bude funkční příklad brzy nasazen na tomto blogu.

Vytvoření kalendáříku obecného

Nejdříve napojíme skripty:

<script src="common.js" type="text/javascript" charset="UTF-8"></script>
<script src="ajax.js" type="text/javascript" charset="UTF-8"></script>
<script src="calendar.js" type="text/javascript" charset="UTF-8"></script>

Potom někam do hlavního skriptu stránky, nebo rovnou do calendar.js připojíme tento skript:

// Tak a teď si vytvoříme kalendář :)
var calendar = new Calendar();
// Den kterým má začít týden
calendar.dayStart = 1; // 0 -> neděle, 1 -> pondělí, 2 -> úterý atd.
// Adresa k PHP skriptu
calendar.path = location.protocol +'//'+ location.host +'/blog/calendar/';
// Prvek kam příjde kalendář
calendar.parentCtg = 'ID prvku';
// Spuštění inicializace a nepřerušení řetězu onloadovacích eventů
var calendarOnload = window.onload;
window.onload = calendarOnload ? function(){calendarOnload();calendar.init()} : calendar.init;

Spackání XMLka v PHPčku

Tento PHP skript je totálně smyšlený na svém blogu používám výhradně řešení dodávané dgx DiBi. Tabulky v MySQLku jsou přibližně takové to:

articles
 -> id
 -> created
 -> url
 -> title
 -> perex
 -> category
 
categories
 -> id
 -> url
 -> name

Skript si ale můžete lehce upravit podle vaší libosti resp. databáze.

<?php
 Header('Content-Type: text/xml');
 $output = "<month>\n";
 // Budete se muset připojit k databázi, jinak vám to opravdu nepůjde...
 $res = mysql_query("SELECT 'articles.id', 'articles.url', 'articles.title', 'articles.perex', 'categories.url' AS 'category_url', 'categories.name' AS 'category_name', DAY('articles.created') AS 'day' FROM 'articles' LEFT OUTER JOIN 'categories' ON ('articles.category' = 'categories.id') WHERE MONTH('articles.created') =".(int)$_GET['month']."AND YEAR('articles.created') =".(int)$_GET['year']."ORDER BY 'day', 'articles.created'");
 $day = '';
 while($article = mysql_fetch_array($res)) {
  if ($day != $article['day']) {
   if ($day) $output .= "\t</day>\n";
   $day = $article['day'];
   $output .= "\t<day date=\"$article[day]\">\n";
  }
  // Pokud máte primitivní URL bez zbytečných mod_url nebo mod_rewrite asi vám stačít něco podobného:
  $output .= "\t\t<article url=\"index.php?article=".$article['id']."\">\n".
  // Jinak já v zájmu Aesthes URL to dělám takhle:
  $output .= "\t\t<article url=\"".BLOG_URL.sprintf(ARTICLE_URL, $article['url'], $article['id'], $article['category_url'])."\">\n".
   "\t\t\t<title>".htmlspecialchars($article['title'])."</title>\n".
   "\t\t\t<category url=\"$article[category_url]\">".htmlspecialchars($article['category_name'])."</category>\n".
   "\t\t\t<perex>".htmlspecialchars($article['perex'])."</perex>\n".
   "\t\t</article>\n";
 }

 if ($day) $output .= "\t</day>\n";
 $output .= "</month>";
echo $output;
?>

A potom jen plácáme a plácáme ručičkami, usmíváme se a posíláme děkovné dopisy s bankovkami.

Trošku užitečné zdrojáky

ajax.js

Třída pro práci s XMLHttpRequest.

//(c)2007 Michal'MiSHAK'Gebauer
function Ajax(){
 this.buffer = [];
 this.finished = [];

 // Zrušení zpracovávání požadavku
 this.abort = function(id){
  for(var i = 0; i < ajax.buffer.length; i++){
   var o = ajax.buffer[i];
   if(!o)
    continue;

   if(o.id == id){
    o.request.abort();
    ajax.buffer.splice(i, 1)
   }
  }
 };

 // Zkontrolování fronty požadavků (interní fce - nepoužívat)
 this.checkBuffer = function(){
  for(var i = 0; i < ajax.buffer.length; i++){
   var o = ajax.buffer[i];
   if(o.doNotCheck)
    continue;

   var xml = o.request;
   if(xml.readyState == 4){
    o.doNotCheck = true;
    if(xml.status == 200 && o.onsuccess){
     o.onsuccess(xml, o.data);
     o.onsuccess = null
    }else if(xml.status != 200 && o.onerror){
     o.onerror(xml, o.data);
     o.onerror = null;
    }
    ajax.buffer.splice(i, 1);
   }
  }
 };

 // Načtení dat z URL, method (GET|POST), data (pole ['prvek', 'hodnota', 'prvek2', 'hodnota2']), onsuccess - fce pro zpracování dat (dostane parametry XML a odeslana data), onerror - fce pro osetření chyb při komunikaci se serverem
 this.load = function(id, url, method, data, onsuccess, onerror){
  var a=false;
  if(window.XMLHttpRequest){
   try{
    a = new XMLHttpRequest();
   }catch(e){
    a = false
   }
  }else if(window.ActiveXObject){
   try{
    a = new ActiveXObject("Msxml2.XMLHTTP");
   }catch(e){
    try{
     a = new ActiveXObject("Microsoft.XMLHTTP");
    }catch(e){
     a = false;
    }
   }
  }
  if(!a)
   return false;

  a.onreadystatechange = ajax.checkBuffer;

  var vars = '';

  if(data){
   var newdata=[];
   for(var x = 0; x < data.length; x += 2){
    var p = data[x], v = data[x + 1];
    vars += (x == 0 ? '' : '&') + p +'='+ v;
    newdata[p] = v;
   }
   data = newdata;
  }

  ajax.abort(id);

  ajax.buffer.push({
   request: a,
   id: id,
   onsuccess: onsuccess,
   onerror: onerror,
   data: data,
   url: url});

  if(method == 'GET' && vars.length)
   url+= '?'+ vars;
  a.open(method, url, true);

  if(method == 'POST'){
   a.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
   a.send(vars);
  }else
   a.send(null);
  return true
 };
}

var ajax = new Ajax();

common.js

//inArray Prototype Array objekt od EmbiMedia @ http://www.embimedia.com/resources/labs/js-inarray.html
Array.prototype.inArray = function(value){for(var i=0;i<this.length;i++){if(this[i]===value){return true}}return false};

//(c)2007 Michal'MiSHAK'Gebauer

// Nastavení tříd(y) elementu
function setClass(obj,Class){
 if(typeof(Class) == 'object')
  for(var i = 0; i < Class.length; i++)
   setClass(obj, Class[i]);

 else if(Class.substring(0,1) != '-') {
  if(!obj.className)
   obj.className = Class;
  else if(obj.className.split(' ').inArray(Class) === false)
   obj.className += ' ' + Class;
 } else
  obj.className = obj.className.replace(new RegExp(" " + Class.substr(1) + "\\b"),'');
}

//Zkratka za document.createTextNode
function t(text, parent) {
 var t = document.createTextNode(text);
 if(parent) (typeof(parent) == 'string' ? document.getElementById(parent) : parent).appendChild(t);
 return t;
}

//Zkratka za document.createElement
function e(name, parent, values, text) {
var n=document.createElement(name);
 if(values)
  for(var x = 0; x < values.length; x += 2)
   n.setAttribute(values[x], values[x+1]);

 if(text) t(text, n);

 if(parent) (typeof(parent)=='string' ? document.getElementById(parent) : parent).appendChild(n);
 return n;
}

//Zkratka za document.getElementById
function eGet() {
 var r = [];
 for(var i = 0; i < arguments.length; i++) {
  var a = typeof(arguments[i]) == 'string' ? document.getElementById(arguments[i]) : arguments[i];

  if(!a) continue;
  r.push(a);
 }
 return arguments.length == 1 ? r[0] : r;
}

// Odstraní element(y)
function eRemove() {
 var r=[];
 for(var i = 0; i < arguments.length; i++) {
  var a = typeof(arguments[i]) == 'string' ? document.getElementById(arguments[i]) : arguments[i];

  if(!a) continue;
  r.push(a.parentNode.removeChild(a))
 }
 return arguments.length == 1 ? r[0] : r;
}

// Vyčistí element(y)
function eClear(){
 var r=[];
 for(var i = 0; i < arguments.length; i++){
  var a = typeof(arguments[i]) == 'string' ? document.getElementById(arguments[i]):arguments[i];

  if(!a) continue;
  while(a.firstChild)
   r.push(a.removeChild(a.firstChild));
 }
 return r;
}

Většina funkcí může za parametr přebírat buď objekt resp. element Node nebo ID prvku, popřípadě pole.

A teď si to můžete stáhnout

Zdrojové kódy můžete použít kde chcete a jak chcete mimo komerční sektor, jen mi pak pošlete odkaz, kde jste je použili.

Stáhnout: calendar.js 0.1, ajax.js 0.1 a common.js 0.1. Šablona pro PHP výstup calendar.txt. Všechno v ZIPu.

8. března 2007 rubrika PHP+AJAX. jeden čtenář Komentáře 4