Předání hodnoty do komponenty – Ajax
- aha009
- Člen | 50
Ahoj, potřeboval bych poradit jak předat změněnou hodnotu (datum)
Ajaxem.
Po kliknutí na odkaz se mi datum změní, ale když odešlu formulář, tak v
processForm
mám původní hodnotu a ne tu, kterou chci nastavit
přes handleDate($date)
. Děkuji
Presenter
final class DietOrderPresenter extends BasePresenter
{
/** @var string */
private $date;
public function actionDefault(): void
{
$date = new DateTime();
$this->date = $date->format('Y-m-d');
protected function createComponentDietOrderForm()
{
$form = $this->dietOrderFormFactory->create($this->date);
$form->onSuccess[] = function (UI\Form $form) {
$this->redrawControl();
};
return $form;
}
public function handleDate($date)
{
$this->date = $date;
if (($this->isAjax())) {
Form
class DietOrderFormFactory extends UI\Control
{
/** @var string */
private $date;
public function create($date)
{
$this->date = $date;
$form = new UI\Form();
$form->onSuccess[] = [$this, 'processForm'];
return $form;
}
public function processForm($form, $values)
{
bdump($this->date);
}
- Polki
- Člen | 553
Takto to neuděláš.
Jelikož každý request je samostatný, tak sena každý request pohlíží
jako na unikát.
Tedy v každém requestu se provede nejdřív action, pak handle, pak render atd..
V tvém případě při prvním vykreslování stránky se nastaví
v action metodě datum na nové (btw. lepší je použít Nette\Utils\DateTime
takto: DateTime::from(‚now‘)->format(‚Y-m-d‘)).
Pak se vykreslí formulář a hotovo.
Potom někdo spustí událost přenastavení data: Spustí se presenter, opět se provede action metoda, která datum nastaví na teď, pak se provede handle, který datum přenastaví na to, co vybral uživatel, pak se vykreslí formulář a hotovo.
Potom ten stejný člověk odešle formulář: Spustí se presenter, provede se action metoda, která nastaví datum na aktuální a pak se vytvoří formulář a zavolá jeho metoda processForm (Callbacky formuláře se chovají jako handle metody.) Jenže jak vidíš, tak se opět provedla action metoda, která nastavila datum na aktuální. (Kdyby si v ní datum nenastavil vůbec, stejně by bylo null, protože to, že se provedl handle v minulém requestu na to nemá vliv. Ten minulý request se změnou data se sice provedl, ale pak se to zahodilo.)
Řešení je třeba takové:
final class DietOrderPresenter extends BasePresenter
{
#[Nette\Application\Attributes\Persistent]
public string $date = '';
public function actionDefault(): void
{
if (!$this->date) {
$this->date = Nette\Utils\DateTime::from('now')->format('Y-m-d');
}
}
protected function createComponentDietOrderForm(): Nette\Application\UI\Control
{
$form = $this->dietOrderFormFactory->create($this->date);
$form->onSuccess[] = function (UI\Form $form) {
$this->redrawControl();
};
return $form;
}
public function handleDate(string $date): void
{
$this->date = $date;
}
}
Čímž jsi udělal z řetězce datumu persistentní parametr předávaný v URL, takže jej budeš mít. Důležité je ale provést ještě validaci, jestli jde opravdu o datum (uživatel může podvrhnout svůj libovolný řetězec) a dát si pozor, aby se v té URL opravdu posílal (Například při ajax requestech, aby se měnila URL.)
Alternativně můžeš využít jakékoliv dočasné úložiště dat. Jen prosím s rozumem.