Závislost tvorby formuláře na jejím uložení při ajaxu
- thirdknown
- Člen | 26
Ahoj,
mám v presenteru ajaxový formulář generovaný pomocí
createComponentSomeForm. V něm mám tlačítko submit s caption
„Provést něco“.
Stisknu-li submit, je zavolán ajaxový požadavek a v něm onSuccess handler, v kterém provedu nějakou „akci“ (logika+DB) a nechám překreslit snippet formuláře, protože v createComponentSomeForm si volím caption pro submit – v DB se ptám, zda byla „akce“ už provedena (jestli to je v DB). Pokud ano, caption bude „Provést něco znovu“.
Jenže – i když je v DB akce uložena tím handlerem, snippet
formuláře se překreslí pouze s caption „Provést něco“, ne „Provést
něco znovu“.
Chápu životní cyklus presenteru. Startup, action, signal (což je
i zpracování formuláře), render, createComponentSomeForm. Jenže když
odešlu formulář, createComponentSomeForm není volán až s render, ale už
při prvním použití SomeForm, tedy signálu zpracování formuláře. Tím
pádem se mi zavolá vytvoření formuláře se starým caption („Provést
něco“) ještě před uložením do DB v signal form handleru.
Moje otázka zní: lze nějak hezky zpracovat formulář ještě před voláním createComponentSomeForm, nebo si musím opravdu na prasáka třeba v action odlovit $_POST nebo request a uložit do DB, aby si createComponentSomeForm už načetla z DB nové hodnoty, tím pádem vytvořila submit s tlačítkem „Provést něco znovu“?
Stránku mám v bootstrap modalu, takže ajax chci používat kvůli tomu, abych nemusel v presenteru ve form handleru používat redirect, čímž by prohlížeč dostal http redirect a tím bych si v důsledku shodil v prohlížeči modal.
Díky!
Editoval thirdknown (7. 4. 2017 23:14)
- Tyraxor
- Člen | 31
Ahoj,
abys mohl formulář zpracovat, tak ho musíš nejdřív vytvořit, jinak
nevíš co máš zpracovávat, tedy volani „createComponentSomeForm“, ale
teoreticky by mělo by jít po zpracování formuláře ho znovu vytvořit a
tím ho naplnit správnýma hodnotama.
Zkus dat po zpracovaní formuláře něco jako:
<?php
$this['someForm'] = $this->createComponentSomeForm();
?>
Editoval Tyraxor (8. 4. 2017 9:19)
- thirdknown
- Člen | 26
@Tyraxor Nejsem si jistý jestli se voláním {control someForm} nevezme už vytvořený formulář. Mohl bych to zkusit.
- thirdknown
- Člen | 26
Kód (napsal jsem zjednodušený příklad mého kódu, aby bylo vše viditelné):
<?php
namespace App\Presenters;
use Nette;
use Nette\Application\UI\Form;
class ArticlePresenter extends Nette\Application\UI\Presenter
{
/** @var Nette\Database\Context @inject */
public $dbContext;
private $idDetail;
public function actionDetail($id)
{
$this->idDetail = $id;
}
public function renderDetail($id)
{
$this->template->countSends = $this->countSends($id);
}
public function createComponentSomeForm()
{
$form = new Form();
$form->getElementPrototype()->class = 'ajax';
$form->addText('message', 'Zpráva')
->setRequired('Vyplňte zprávu');
if ($this->existsAtLeastOneSend($this->idDetail)) {
$submitCaption = 'Odeslat znovu';
} else {
$submitCaption = 'Odeslat poprvé';
}
$form->addSubmit('submit', $submitCaption);
$form->onSuccess[] = [$this, 'processSomeForm'];
return $form;
}
public function processSomeForm(Form $form, $values)
{
$this->registerSend($this->idDetail, $values['message']);
$this->flashMessage('Odeslání bylo úspěšné');
if ($this->isAjax()) {
$this->redrawControl('someForm');
$this->redrawControl('countSends');
$this->redrawControl('flashes');
} else {
$this->redirect('this');
}
}
public function registerSend($idArticle, $message)
{
$this->dbContext->table('article_sends')->insert([
'id_article' => $idArticle,
'message' => $message,
]);
}
public function existsAtLeastOneSend($idArticle)
{
return (bool) $this->countSends($idArticle);
}
public function countSends($idArticle)
{
return $this->dbContext->table('article_sends')->where([
'id_article' => $idArticle,
])->count();
}
}
View:
{block content}
{snippet countSends}
Počet odeslání: {$countSends}
{/snippet}
{snippet someForm}
{control someForm}
{/snippet}
- thirdknown
- Člen | 26
Myslím, že jsem problém vyřešil tak, že submit caption generuji až
v latte.
Změny:
public function renderDetail($id)
{
$this->template->idArticle = $id;
$this->template->countSends = $this->countSends($id);
}
public function createComponentSomeForm()
{
$form = new Form();
$form->getElementPrototype()->class = 'ajax';
$form->addText('message', 'Zpráva')
->setRequired('Vyplňte zprávu');
$form->addSubmit('submit');
$form->onSuccess[] = [$this, 'processSomeForm'];
return $form;
}
View:
{block content}
{snippet countSends}
Počet odeslání: {$countSends}
{/snippet}
{snippet someForm}
{form someForm}
{input message}
{if $presenter->existsAtLeastOneSend($idArticle)}
{var $submitCation = 'Odeslat znovu'}
{else}
{var $submitCation = 'Odeslat poprvé'}
{/if}
<input n:name="submit" value="{$submitCation}">
{/form}
{/snippet}
Třeba to někomu pomůže.
- David Matějka
- Moderator | 6445
taky bys to mohl vyresit tak, ze po zpracovani formulare zmenis caption:
$this->registerSend($this->idDetail, $values['message']);
$form['submit']->caption = 'Odeslat znovu';