Okosítsunk
Ha még nem olvastad, olvasd el előbb ezt a bejegyzést: CRUD – PDO – 1. rész
Többé kevésbé működik már a programunk, de azért két hibája van: buta és csúnya. Ebben a részben próbáljuk egy kicsit felokosítani. Egyrészt a törlést is illene külön fájlban megvalósítani (Titkolt cél volt annak bemutatása, hogy az index.php állományra is rábízhatjuk a feladatok megvalósítását.), illetve ki tudná a törlésnél és a szerkesztésnél kitalálni, hogy mi a törlendő rekord azonosítója. Sokkal jobb lenne a törlendő rekordot egy listából kiválasztani. Ezt is megvalósítjuk. Harmadjára pedig a keresést írjuk át úgy, hogy a beírás pillanatában már frissítse a találatok listáját. Vágjunk is bele!
Lehulló lista használata
Nagyon könnyű dolgunk van a lehulló lista megvalósítására a Delete és az Edit űrlapokban, hiszen a $data változó tartalmazza már az adatbázisunk adatait (az index.php betöltésekor kérdezzük le ezeket az adatokat), és így csak ebből kell egy ciklussal kiírni a megfelelő HTML tag-eket. A későbbiekben látni fogjuk, hogy most nem itt fogjuk feldolgozni az Edit és a Delete űrlapot, így az ezekhez tartozó kódokat is töröljük. Végeredményben ilyen egyszerűen néz majd ki az index.php elején a php szakasz:
<?php require_once("db.php"); $db = new DB(); $data = $db->getData(); ?>
Az új Delete és Edit űrlapunk ennek megfelelően így fog kinézni:
<h3>Delete</h3> <form method="POST"> <select name="id" id="deleteList"> <?php foreach($data as $item) { ?> <option value="<?php echo $item['id'] ?>"><?php echo $item['id'] . ' - ' . $item['name'] ?></option> <?php } ?> </select> <input type="submit" value="Delete" name="deleteData"> </form>
<h3>Edit</h3> <form action="editdata.php" method="POST"> <select name="id" id="deleteList"> <?php foreach($data as $item) { ?> <option value="<?php echo $item['id'] ?>"><?php echo $item['id'] . ' - ' . $item['name'] ?></option> <?php } ?> </select> <input type="text" placeholder="Name" name="name"> <input type="submit" value="Edit" name="editData"> </form>
A törlés PHP állománya
A törlést megvalósító metódust már megírtuk a DB osztály definíciójában deleteData() néven, csak eddig ezt az index.php-ból hívtuk meg. Ezt a kódrészt is töröljük innen, és a törlés űrlapját kiegészítjük, hogy a deletedata.php állományt hívja meg.
<h3>Delete</h3> <form action="deletedata.php" method="POST"> <select name="id" id="deleteList">
A deletedata.php állományunk kódja teljesen egyértelmű: Amennyiben a deleteData gombra kattintottak, kiemeljük a $_POST tömbből a törlendő rekord azonosítóját, létrehozzuk a DB objektumot, és meghívjuk a deleteData() metódusát. Ezek után visszatérünk az index.php állományra.
<?php require_once "db.php"; if(isset($_POST['deleteData'])){ $id = $_POST['id']; $db = new DB(); $db->deleteData($id); header('Location: index.php'); } ?>
Valós idejű keresés
A legnagyobb változtatást az adatok keresésében hajtjuk végre. Megvalósítjuk azt, hogy a karakterek beírása közben azonnal lekérdezzük a beírt karaktersorozatnak megfelelő adatokat az adatbázisból, vagyis nincsen szükségünk a beírt név manuális elküldésére. Először is amellett, hogy töröljük a Submit gombot a keresés űrlapjából, kiegészítjük a beviteli mezőt az onkeyup() eseménykezelővel, amelyben meghívjuk a searchNames() javascript függvényt, átadva neki a mező tartalmát. (A FORM method paraméterét is átírjuk POST-ra, de ennek itt nem lesz jelentősége.)
<h3>Search</h3> <form method="POST"> <input type="text" placeholder="Name" name="name" onkeyup="searchNames(this.value)"> </form>
A searchNames() javascript függvényt a main.js fájlban definiáljuk. A main.js állományt a záró </body> tag előtt töltjük be az index.php állományban:
<script src="main.js"></scrip>
Definiáljuk a main.js állományban a searchNames() függvényt, és tesztelési célból annyi kódot írjunk be, hogy az átvett paramétert (amit beírtunk. beviteli mezőbe) írja ki a konzolra. Próbáljuk ki! (A beírt karakterek sorban megjelennek a konzolon.)
function searchNames(name){ console.log(name); }
Ha minden működik, menjünk tovább. A terv az, hogy ez a searchNames() függvény fogja meghívni a searchdata.php állományunkat, melynek feladata a bevitt adatoknak megfelelő rekordok lekérdezése. A programnak csupán az utolsó sora igényel magyarázatot. Mivel a Javascript program JSON formátumban várja a php kimenetét, ezért azt a json_encode() függvénnyel erre formátumra hozzuk.
<?php require_once("db.php"); $name = $_POST["name"]; $db = new DB(); $data = $db->searchData($name); echo json_encode($data); ?>
Nézzük tovább a searchNames() függényünket. Találunk benne pár újszerű megoldást. Mivel nem tudjuk, hogy az adatbázis lekérdezése mennyi ideig tart, ezért aszinkron feldolgozást valósítunk meg. Az első lépésben a fetch() függvénnyel átadjuk a vezérlést a searchdata.php állománynak. A POST metódust használjuk, és egy URLSearchParams objektummal átadjuk a keresendő nevet. A fetch() egy promise (ígéret) objektumot ad vissza, mely a lekérdezést eredményét tartalmazza majd. Ez nem a serchdata.php kimenete JSON formátumban, hanem egy HTTP response objektum. Ezt adjuk tovább a then() metódusnak, és a kimenetet, vagyis a lekérdezett adatokat JSON formátumban a json() metódussal nyerjük ki a response objektumból. Ezt tovább adjuk a következő then() metódusnak, amely már meghívja a populateTable() függvényt, mely a HTML oldalon megjeleníti a lekérdezett adatokat egy táblázat törzsében. (Felépíti a táblázat törzsét a DOM-ban.) Amennyiben hiba történt a fetch() során, a catch() metódus hajtódik végre.
function searchNames(name) { fetch('searchData.php', { method: 'POST', body: new URLSearchParams('name=' + name) }).then(function (res) { return res.json(); }).then(function (data) { populateTable(data); }).catch(function (e) { }) }
Érdemes megnézni a populateTable() függvény számára átadott argumentumot, így jobban fogjuk érteni a függvény működését. (A kimenetet a böngésző konzolára írtuk ki a console.log(data) függvényhívással.)
0: {id: "5", name: "Bill", email: "bill@gmail.com"} 1: {id: "9", name: "Bob", email: "bob@gmail.com"} 2: {id: "11", name: "Rob", email: "rob@gmail.com"} 3: {id: "12", name: "Bill2", email: "bill2@gmail.com"}
Ezen a tömbön lépkedünk végig, és létrehozva a HTML tábla egyes elemeit, beépítjük a DOM-ba az adatokat:
function populateTable(data) { table = document.querySelector(".data-table"); table.innerHTML = ""; for (let i = 0; i < data.length; i++) { const trDataContainer = document.createElement("tr"); table.appendChild(trDataContainer); let newId = document.createElement("td"); newId.innerHTML = data[i]["id"]; trDataContainer.appendChild(newId); let newName = document.createElement("td"); newName.innerHTML = data[i]["name"]; trDataContainer.appendChild(newName); } }
Már csak egyetlen dolgot kell megoldanunk: Az oldal betöltődésekor meg kellene jeleníteni az adatbázis adatait az oldalon. Ehhez a <body> tag-hez rendeljük az onload eseménykezelőt, amely meghívja egy üres karakterrel a searchNames() függvényt:
<body onload="searchNames('')">
Ennyi volt. Persze tovább okosíthatnánk a programot (például további hibakezelésekkel, stb.), de legyen ennyi elég. A következő részben próbáljuk egy kicsit kicsinosítani az oldalt. Ehhez egy kis CSS ismeretre lesz szükség.
Ha érdekelt a bejegyzés, olvasd el ezt is: CRUD – PDO – 3. rész