Nyomtatvány rekord létrehozásához és szerkesztéséhez
Hogyan lehet megfelelően megvalósítani egy rekord hozzáadását és szerkesztését a Nette-ben, ugyanazt az űrlapot használva mindkettőhöz?
Sok esetben a rekord hozzáadására és szerkesztésére szolgáló űrlapok azonosak, csak a gomb címkéje különbözik. Példákat mutatunk egyszerű bemutatókra, ahol az űrlapot először egy rekord felvételére, majd szerkesztésére használjuk, végül pedig a két megoldást kombináljuk.
Rekord hozzáadása
Egy példa egy rekord hozzáadására használt prezenterre. A tényleges adatbázis-munkát a Facade
osztályra
hagyjuk, amelynek kódja a példa szempontjából nem releváns.
use Nette\Application\UI\Form;
class RecordPresenter extends Nette\Application\UI\Presenter
{
public function __construct(
private Facade $facade,
) {
}
protected function createComponentRecordForm(): Form
{
$form = new Form;
// ... űrlapmezők hozzáadása ...
$form->onSuccess[] = [$this, 'recordFormSucceeded'];
return $form;
}
public function recordFormSucceeded(Form $form, array $data): void
{
$this->facade->add($data); // rekord hozzáadása az adatbázishoz.
$this->flashMessage('Sikeresen hozzáadva');
$this->redirect('...');
}
public function renderAdd(): void
{
// ...
}
}
Felvétel szerkesztése
Most nézzük meg, hogyan nézne ki egy rekord szerkesztésére használt prezenter:
use Nette\Application\UI\Form;
class RecordPresenter extends Nette\Application\UI\Presenter
{
private $record;
public function __construct(
private Facade $facade,
) {
}
public function actionEdit(int $id): void
{
$record = $this->facade->get($id);
if (
!$record // ellenőrizze a nyilvántartás meglétét
|| !$this->facade->isEditAllowed(/*...*/) // engedélyek ellenőrzése
) {
$this->error(); // 404 hiba
}
$this->record = $record;
}
protected function createComponentRecordForm(): Form
{
// ellenőrizze, hogy a művelet 'szerkesztés'
if ($this->getAction() !== 'edit') {
$this->error();
}
$form = new Form;
// ... űrlapmezők hozzáadása ...
$form->setDefaults($this->record); // alapértelmezett értékek beállítása
$form->onSuccess[] = [$this, 'recordFormSucceeded'];
return $form;
}
public function recordFormSucceeded(Form $form, array $data): void
{
$this->facade->update($this->record->id, $data); // rekord frissítése
$this->flashMessage('Sikeresen frissítve');
$this->redirect('...');
}
}
Az action metódusban, amelyet a prezenter életciklusának kezdetén hívunk meg, ellenőrizzük a rekord létezését és a felhasználó engedélyét a szerkesztésre.
A rekordot a $record
tulajdonságban tároljuk, hogy a createComponentRecordForm()
metódusban az
alapértelmezések beállításához, valamint a recordFormSucceeded()
azonosítóhoz rendelkezésre álljon. Egy
alternatív megoldás az lenne, ha az alapértelmezett értékeket közvetlenül a actionEdit()
-ban állítanánk
be, és az ID értékét, amely az URL része, a getParameter('id')
segítségével kérnénk le:
public function actionEdit(int $id): void
{
$record = $this->facade->get($id);
if (
// ellenőrzi a létezést és a jogosultságokat
) {
$this->error();
}
// alapértelmezett űrlapértékek beállítása
$this->getComponent('recordForm')
->setDefaults($record);
}
public function recordFormSucceeded(Form $form, array $data): void
{
$id = (int) $this->getParameter('id');
$this->facade->update($id, $data);
// ...
}
}
Azonban, és ez lesz a legfontosabb tanulság az egész kódból, meg kell győződnünk arról, hogy a művelet
valóban edit
, amikor létrehozzuk az űrlapot. Mert különben a actionEdit()
metódusban az
érvényesítés egyáltalán nem történne meg!
Ugyanaz az űrlap a hozzáadáshoz és a szerkesztéshez
És most egyesítjük a két előadót egybe. Vagy megkülönböztetjük, hogy melyik műveletről van szó a
createComponentRecordForm()
módszerben, és ennek megfelelően konfiguráljuk az űrlapot, vagy közvetlenül az
action-módszerekre bízzuk, és megszabadulunk a feltételtől:
class RecordPresenter extends Nette\Application\UI\Presenter
{
public function __construct(
private Facade $facade,
) {
}
public function actionAdd(): void
{
$form = $this->getComponent('recordForm');
$form->onSuccess[] = [$this, 'addingFormSucceeded'];
}
public function actionEdit(int $id): void
{
$record = $this->facade->get($id);
if (
!$record // ellenőrizze a nyilvántartás meglétét
|| !$this->facade->isEditAllowed(/*...*/) // engedélyek ellenőrzése
) {
$this->error(); // 404 hiba
}
$form = $this->getComponent('recordForm');
$form->setDefaults($record); // alapértelmezett értékek beállítása
$form->onSuccess[] = [$this, 'editingFormSucceeded'];
}
protected function createComponentRecordForm(): Form
{
// ellenőrizze, hogy a művelet "hozzáadás" vagy "szerkesztés".
if (!in_array($this->getAction(), ['add', 'edit'])) {
$this->error();
}
$form = new Form;
// ... űrlapmezők hozzáadása ...
return $form;
}
public function addingFormSucceeded(Form $form, array $data): void
{
$this->facade->add($data); // rekord hozzáadása az adatbázishoz.
$this->flashMessage('Sikeresen hozzáadva');
$this->redirect('...');
}
public function editingFormSucceeded(Form $form, array $data): void
{
$id = (int) $this->getParameter('id');
$this->facade->update($id, $data); // rekord frissítése
$this->flashMessage('Sikeresen frissítve');
$this->redirect('...');
}
}