Ajax a formulare – snippety se updatuji, formulare ne!
- peci1
- Člen | 60
Ahoj, mam jednoduchy formular (AppForm s ConventionalRenderer, vykreslovany pomoci widget bez zavinace), ktery chci po odeslani zobrazit (AJAXove) v aktualizovane podobe. Celkem trivialni ukol. Nainkludoval jsem javascripty atd., @ v layoutu mam.
A ted – o co jde? Pokud formular odeslu, tak uz se mi v payloadu nevrati;
ve formulari mam
<?php
$this['submit']->onClick[] = array($this, 'questionsFormSubmitted');
?>
(onClick proto, ze tlacitek je tam vic s ruznymi funkcemi)
A v metode questionsFormSubmitted invaliduju formular (je vytvaren tovarnickou, ze by problem pramenil odsud?) a snippet:
<?php
$this->invalidateControl('flashes');
//nekde jsem cetl, ze komponenta, ktera dostava signal, je invalidovana
//automaticky, ale jistota je jistota (OT: je vubec handler odeslani
//formulare bran jako signal?)
$this->invalidateControl('questionsForm');
?>
Jak uz jsem psal, snippet flashes se spravne aktualizuje, ale form se vubec neposle. S vypnutym JS se formular chova spravne.
Kdyz si v render necham vypsat $this->isControlInvalid(‚questionsForm‘), vrati mi true…
Nevite prosim nekdo, kde chybuju?
BTW: nestalo by za to integrovat odesilani formularu ajaxem primo do frameworku?
Nette Framework 0.9 (revision c82239a released on 2009–08–17)
Editoval peci1 (28. 9. 2009 1:35)
- DocX
- Člen | 154
<?php
$this->invalidateControl('questionsForm');
?>
Neinvaliduje komponentu, ale snippet. K invalidaci kompenenty použij
<?php
$this['questionForm']->invalidateControl();
?>
To ale asi není co chceš. Obal widget snipetem a invaliduj snippet (jako původní kód):
{snippet questionForm}
{control questionForm}
{/snippet}
- Honza Kuchař
- Člen | 1662
e vubec handler odeslani formulare bran jako signal?
Ne, je to callback
Editoval honzakuchar (28. 9. 2009 8:00)
- peci1
- Člen | 60
DocX napsal(a):
Neinvaliduje komponentu, ale snippet. K invalidaci kompenenty použij
<?php $this['questionForm']->invalidateControl(); ?>
Jelikoz AppForm neni control, nema ani metodu invalidateControl. To by ale nevadilo, protoze – jak jsem psal – v render fazi mi dotaz na $this->isControlInvalid(‚questionForm‘) vrati true, takze komponenta JE invalidovana, jen se neposle. Kdyz ale ten form neni control, muze byt vubec invalidovan?
Obaleni snippetem funguje, diky! Jen mi prijde, ze to neni uplne nejcistsi reseni…
Editoval peci1 (28. 9. 2009 8:09)
- Honza Kuchař
- Člen | 1662
nejcistsi reseni…
Pokud vím, jiné není.
//EDIT: Vychází to z historie Nette. Forms byli jedny z prvních veřejných a doteď fungují i samostatně – bez Nette. → Nemůžou být komponenta se snippetem.
Ještě si dej bacha při tom odesláná formuláře! On se totiž mus invalidovat i když byl odeslán a byl nevalidní! Jinak se uživatelovi nezobrazí co udělal špatně. Já to řeším takhle:
public function createComponentForm($name) {
$form = new AppForm($this, $name);
/* ... */
$form->onSubmit[] = array($this,"onSubmit");
// Invalidace snippetů
$form->onInvalidSubmit[] = array($this,"handlePrekresliForm");
$form->onSubmit[] = array($this,"handlePrekresliForm");
}
public function onSubmit(Form $form) {
$data = $form->getValues();
/* ... */
}
public function handlePrekresliForm() {
$this->invalidateControl("form");
}
Editoval honzakuchar (28. 9. 2009 8:08)
- redhead
- Člen | 1313
honzakuchar napsal(a):
//EDIT: Vychází to z historie Nette. Forms byli jedny z prvních veřejných a doteď fungují i samostatně – bez Nette. → Nemůžou být komponenta se snippetem.
Pokud vím tak AppForm se může použít jen v aplikaci, čili nikoliv samostatně (jako Form). Takže by se to mohlo upravit. Ale implementaci jsem nezkoumal, tak nevím jestli to nebude komplikované.
- DocX
- Člen | 154
peci1 napsal(a):
Obaleni snippetem funguje, diky! Jen mi prijde, ze to neni uplne nejcistsi reseni…
On ten snippet uděla 2 důležité věci:
- Vloží do html
<div id="__snippet"></div>"
. To aby JS vůbec vědělo kam kód poslaný PHPkem dát. - Při zpracování PHP zachytí výstup uvnitř snippetu. To aby věděl co má v JS payloadu poslat.
Editoval DocX (28. 9. 2009 11:01)
- DocX
- Člen | 154
peci1 napsal(a):
DocX napsal(a):
BTW:
Proč tohle není někde v dokumentaci? Nebo jsem to nenašel? Nebo je to záměrně utajovaná záležitost?
Mam stejny pocit… Myslim, ze to neni uplne neobvykla cinnost, az jsem se divil, ze jsem to ani na foru nenasel…
No je fakt, že se na řešení dá jakž takž přijít. A zase nelze očekávat od všeho automatiku (to by za chvíli programátoři nadávali jako dělníci za dob průmyslové revoluce :). Nicméně třeba zde by o tom nějaké zmínka být mohla :)