AJAX a Nette – první setkání – snippet uvnitř formuláře háže chybu
- svezij
- Člen | 69
Ahojte, předem se chci omluvit, jestli je to hloupá otázka, toto je má první zkušenost s AJAXem v Nette. Mám formulář a uvnitř formuláře tabulku s nějakými daty, konkrétně se jedná o seznam obrázků. Mám to vykresleno následujícím způsobem:
{form uploadImagesForm}
{* tady je možné uploadovat nové obrázky *}
{input images} {input upload}
{* tady je seznam již uložených obrázků *}
<h3>Uložené obrázky</h3>
{snippet saved_images}
<table>
<tbody>
{foreach $images as $image}
<tr>
<td class="preview"><img src="{$basePath}/{$cesta_k_obrazku}/{$image->id}.jpg" /></td>
<td class="name">{var $name = 'saved_name_' . $image->id}{input $name}</td>
<td class="delete">
<a n:href="deleteImage! $image->id" class="ajax">Smazat</a>
</td>
</tr>
{/foreach}
</tbody>
</table>
{/snippet}
{input save}
{/form}
Problém je, že když to mám takto, tak mi laděnka háže tuto chybu
(označený řádek je ten s inputem saved_name_ID
):
Undefined variable: _form
<?php $name = 'saved_name_' . $image->id ;$_input = (is_object($name) ? $name : $_form[$name]); echo $_input->getControl()->addAttributes(array()) ?>
Když odeberu snippet z formuláře, formulář se v pořádku načte, ale
při zavolání invalidateControl()
se neinvalidují změny. Když
kliknu na odkaz Smazat
, tak se provede smazání obrázku, ale
tabulka zůstane stejná, nepřekreslí se. V prezenteru mám tento kód
(v metodě handleDeleteImage($imageId)
sledujte, prosím,
popisky):
/**
* Creates form.
*
* @param string $name
* @return Nette\Application\UI\Form
*/
protected function createComponentManageProductImagesForm($name)
{
$form = new Form($this, $name);
...
}
/**
*
* @param int $imageId
*/
public function handleDeleteImage($imageId)
{
$this->productImageRepository->deleteImage($imageId);
if (!$this->presenter->isAjax()) {
$this->presenter->redirect('this');
} else {
// a) následující volání skončí kódem 500 a chybou: 500 (Internal Server Error)
$this['uploadImagesForm']->invalidateControl();
// b), c) ani jedno z následujících volání nepřekreslí tabulku s uloženými obrázky
$this->invalidateControl();
$this->invalidateControl('uploadImagesForm');
}
}
Zkusil jsem tedy ještě jednu věc, a to obalit celý formulář do snippetu a invalidovat ten, ale stále se nic nepřekreslí.
{snippet obalFormulare}
{form uploadImagesForm}
...
{/form}
{/snippet}
{* a v metodě handleDeleteImage($imageId) pak $this->invalidateControl('obalFormulare'); *}
Omlouvám se také, jestli už zde bylo něco podobného řešené (pravděpodobně ano), něco jsem prošel, ale bohužel mě nenapadlo řešení. Co dělám špatně, a co / jak bych měl změnit? Děkuji.
- svezij
- Člen | 69
Opět zdravím, našel jsem tento příspěvek
(který mimochodem odkazuje na článek Dependent
form select with AJAX) a poskytl jsem šabloně svůj formulář. Upravil
jsem i metodu handleDeleteImage($imageId)
tak, že jsem předal do
šablony nově upravené images a vše funguje :-). Řešení:
Latte:
{form uploadImagesForm}
{* tady je možné uploadovat nové obrázky *}
{input images} {input upload}
{* tady je seznam již uložených obrázků *}
<h3>Uložené obrázky</h3>
{snippet saved_images}
<table>
<tbody>
{foreach $images as $image}
<tr>
<td class="preview"><img src="{$basePath}/{$cesta_k_obrazku}/{$image->id}.jpg" /></td>
<td class="name">{var $name = 'saved_name_' . $image->id}{input $name}</td>
<td class="delete">
<a n:href="deleteImage! $image->id" class="ajax">Smazat</a>
</td>
</tr>
{/foreach}
</tbody>
</table>
{/snippet}
{input save}
{/form}
Presenter->render<View>() (nebo Presenter->action<Action>()):
public function action<Action>()
{
...
$this->template->_form = $this['uploadImagesForm'];
...
}
Presenter->handleDeleteImage($imageId):
public function handleDeleteImage($imageId)
{
$this->imageRepository->delete($imageId);
if (!$this->presenter->isAjax()) {
$this->presenter->redirect('this');
} else {
$this->template->images = $this->imageRepository->findAll();
$this->invalidateControl('saved_images');
}
}
Tohle mi ještě chvíli nefungovalo, ale jelikož mi po kliknutí na
„Smazat“ zmizel náhled obrázku, došlo mi, že musím šabloně znovu
předat upravené obrázky
$this->template->images = $this->imageRepository->findAll();
.
Snad je vše srozumitelné a snad je tohle řešení v pořádku.
Díky :-).