A minap találkoztam össze a twofifty.org oldallal, ahol az ember trendi Ajax-os rendszer segítségével kihuzogathatja az IMDb 250-es listából azokat a filmeket, amiket látott. Meg mellesleg kommenteket is lehet hozzá fűzni, meg vannak statisztikák is nem, kor szerinti bontásban. Amellett, hogy meglepően kevés filmet láttam ebből a listából, eszembe jutott, hogy mekkora jó lenne már egy olyan kis alkalmazás, ahol az ember a tennivalóit tudná hasonló módon kihuzogatni. Gyorsan össze is dobtam egy ilyen kis oldalacskát a Prototype és a PDO segítségével.

Először talán kezdjük az adatbázis táblával, ami roppant egyszerű lesz, mivel nem akartam a dolgot túlbonyolítani, csak egyszerűen kedvet éreztem egy ilyen kis rendszer megvalósításához:

CREATE TABLE `todo` (
	`ID` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
	`description` TEXT NOT NULL,
	`status` ENUM('0', '1') NOT NULL DEFAULT '0'
) ENGINE = MYISAM;

Persze adatok se ártanak bele:

INSERT INTO `todo` (`ID`, `description`, `status`) VALUES
(NULL, 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.', '0'),
(NULL, 'Suspendisse luctus, sem at pretium interdum, dolor velit pellentesque turpis, eu volutpat velit neque vel nulla.', '0'),
(NULL, 'Praesent ligula dolor, vehicula sed, facilisis ac, gravida et, elit. Morbi id urna.', '0');

Aztán a HTML-PHP vonallal folytattam a munkát, a következő pár soros kód legenerálja nekünk a listát (aki esetleg nem mozog annyira otthonosan a PDO világában, annak tudom ajánlani egy régebbi bevezető jellegű írásomat):

print '<div id="error">&nbsp;</div>';
print '<ul id="todo">';
$db = new PDO('mysql:host=localhost;dbname=database', 'user', 'password');
foreach ($db->query("SELECT * FROM `todo`") as $row) {
	print '<li id="task-'.$row['ID'].'"'.($row['status'] === '1' ? ' class="done"' : ' class="not-done"').'>'.htmlspecialchars($row['description']).'</li>';
}
$db = NULL;
print '</ul>';

Ez után már tényleg nincs is más hátra, mint a Prototype segítségével megírni a szükséges JavaScript kódot. Először is az oldal betöltődése után az összes listatagnak elkezdjük figyelni a click eseményét:

Event.observe(window, 'load', function(e) {
	var todos = $('todo').getElementsByTagName('li');

	for (var i = 0; i < todos.length; ++i) {
		Event.observe(todos[i], 'click', listElementClick);
	}
});

Miután ez megvan, már nincs más dolgunk, mint a listElementClick nevezetű függvény, ami annyit tesz, hogy az adott ID-jű feladat státuszát az adatbázisban megváltoztatja, majd siker esetén a listaelem stílusát az új státuszhoz igazítja (ha 'done' volt akkor 'not-done' lesz, ha 'not-done' volt, akkor pedig 'done').

function listElementClick(e) {
	$('error').innerHTML = '&nbsp;';

	var t;
	if (e.srcElement) t = e.srcElement;
	else t = e.target;

	var tmp = t.id.split('-');
	var ID = tmp[1];
	var status = 0;

	if (t.className == 'not-done') status = 1;
	else status = 0;

	/* ... */
}

Nos, ezzel így még nem sok mindent csináltunk, csak előkészítettük a terepet a /* ... */ helyére kerülő Ajax kérésnek, ami pedig a következő lesz:

var req = new Ajax.Request(
	'process.php',
	{
		method     : 'post',
		parameters : 'ID='+ID+'&status='+status,
		onComplete : function(req) {
			var response_status = req.responseText.split(',');

			if (response_status[0] == '1') {
				$('task-'+response_status[1]).className = response_status[2];
			}
			else {
				$('error').innerHTML = 'Nem sikerült módosítani a tennivaló státuszát!';
			}
		}
	}
);

Már csak a process.php tartalma van hátra, ami tulajdonképpen elvégzi a szükséges adatbázis műveleteket és visszatér egy [módosítás státusza],[feladat ID-je],[új css osztály neve] formátumú listával.

header('Content-Type: text/plain');

if (isset($_POST['ID']) && isset($_POST['status'])) {
	try {
		$db = new PDO('mysql:host=localhost;dbname=database', 'user', 'password');
		$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

		$db->query("UPDATE `todo` SET `status`='".(int)$_POST['status']."' WHERE `ID`='".(int)$_POST['ID']."'");

		echo '1,'.$_POST['ID'].','.($_POST['status'] === '1' ? 'done' : 'not-done');
	}
	catch (PDOException $e) {
		echo '0';
	}
}
else {
	echo '0';
}

És ha minden kis darabkát sikerült a megfelelő helyre illesztenünk, akkor az oldalt betöltve kattintgathatjuk is a feladatokat, ami nagyszerűen látszik is, ha megfelelő CSS-t is csatolunk a dokumentumunkhoz. Valami ilyesmi egyszerű meg is teszi:

#todo li {
	cursor: pointer;
}
.done {
	color: gray;
	text-decoration: line-through;
}
.not-done {
	color: black;
	text-decoration: none;
}
#error {
	font-size: 14px;
	color: red;
	font-weight: bold;
}

Ezzel meg is volnánk. Mint azt az elején is említettem, nem bonyolítottam túl a dolgokat semmiféle extrával. A működő példa megtekinthető itt.

++++-

Hozzászólások Hozzászólások RSS

  1. A nem működő példa pedig localhost-on létezik.. debuggolni az én ismereteimmel lehetetlen, úgyhogy király. Először arra hivatkozott IE-ben, hogy a JS Event objektum nem létezik, aztán megcseréltem a sorrendet, hát azóta nincs hiba, viszont kattintásra se reagál semmit a kedves program, és így elég nehezen tudom kitalálni mi gondja van :\ I'm too lame for this.. http://ajax.tommey.hu/todo_process.txt, itt a két fájl egymás után, persze eredetiben két fájl, csak az egyszerűség kedvéért egy, és a kérdés: mi a hiba? :(

  2. Így első rálátásra, a todo.php <head> részéből hiányzik egy olyasmi sor, hogy <script type="text/javascript" src="prototype.js"></script>. A prototype.js pedig beszerezhető innen. A működő példa letölthető változata pedig innen.

  3. Csak sikerült :) köszönöm a segítséget, viszont azt nem értem, hogy miért olyan lassú :( kattintás után 4-5másodperc is eltelik mire változik a helyzet, de tudom, hogy ez az én gépem hibája, csak nem értem, hogy miért.. minden sql lekérdezéssel rendelkező oldal egy csomó idejig töltődik, és nem értem miért. Legújabb php, mysql van fenn, ill. apache 2.0.59., mert a 2.2-t nem tudom feltenni, valamiért nem hajlandó működni egyáltalán :( ötlet a lassúságra? mert így teljesen értelmetlen az ajax, gyorsabban újratöltődik az oldal..

Szólj hozzá!

regisztráció, bejelentkezés

Az oldalon nem jelenik meg.

Ezeket a tageket használhatod: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

*