Nefunguje invalidace u ajaxoveho formulare
- tomasnikl
- Člen | 137
Ahoj,
prosim vas, asi mam nekde chybu a uz nevim kde ji mam hledat. Mam jednoduchy formular, ktery bych chtel odesilat ajaxove. Tedy:
Presenter:
public function renderAdd()
{
}
protected function createComponentAddForm()
{
$form = new \Nette\Application\UI\Form;
$form->getElementPrototype()->class('ajax');
$form->addText('name', 'Jméno:')->setRequired('Zadejte prosím jméno');;
$form->addSubmit('submit', 'Odeslat');
$form->onSuccess[] = callback($this, 'addFormSubmitted');
return $form;
}
public function addFormSubmitted($form)
{
$values = $form->getValues();
if($this->isAjax()){
$this->presenter->invalidateControl('form');
}else{
$this->redirect('this');
}
}
sablona add.latte:
{block content}
{snippet form}
{control addForm}
{/snippet}
{/block}
a javascript jsem pouzil z doplnku zde na webu pro jQuery. Formualr se opravdu odesle ajaxove a je vraceno:
"<form action="/e/www/admin/pages/add?do=addForm-submit" method="post" id="frm-addForm" class="ajax">
<table>
<tr class="required">
<th><label class="required" for="frmaddForm-name">Jméno:</label></th>
<td><input type="text" class="text" name="name" id="frmaddForm-name" required="required" data-nette-rules="{op:':filled',msg:"Zadejte pros\u00edm jm\u00e9no"}" value="asd" /></td>
</tr>
<tr>
<th> </th>
<td><input type="submit" class="button" name="submit_" id="frmaddForm-submit" value="Odeslat" /></td>
</tr>
</table>
<div><!--[if IE]><input type=IEbug disabled style="display:none"><![endif]--></div>
</form>
"
a jak je videt, v jsonu je u inputu
value="asd"
coz by byt asi nemelo, kdyz chci docilit toho, aby se po odeslani formular vyprazdnil.
Nevidite prosim v kodu nejakou chybu prosim?
Dekuji
- tomasnikl
- Člen | 137
Tak jsem vyzkousel, vytvoril jsem si novy snippet v sablone, a ten se mi neinvalidoval, zda to pisu spravne. V tomto novem snippetu jsem z presenteru predaval promenou test s hodnotou XXX a po odeslani formulare jsem jeji hodnotu chtel zmenit na YYY.. v sablone ovsem i po odeslani formulare je text XXX, takze ani snippet bez formulare se nezmenil. Takze chyba bude asi zde, ze se neinvaliduje snippet.
Jinak promena payload je naplnena. Je v ni snippet s formularem
jeste jednou ukazu aktualni kod:
Presenter:
public function renderAdd()
{
$this->template->test = 'test1';
}
protected function createComponentAddForm()
{
$form = new \Nette\Application\UI\Form;
$form->getElementPrototype()->class('ajax');
$form->addText('name', 'Titulek stránky:')
->setRequired('Zadejte prosím titulek stránky')
->getControlPrototype()->class('slug-title');
$form->addText('menu_name', 'Titulek v menu:');
$form->addText('slug', 'URL slug:')
->setRequired('Zadejte prosím URL slug')
->getControlPrototype()->class('slug');;
$form->addSelect('status', 'Viditelnost:', array(1=>'Viditelná', 0=>'Skrytá'));
$form->addText('head_title', 'Titulek v hlavičce:');
$form->addTextArea('head_description', 'Popis stránky v hlavičce:');
$form->addText('head_keywords', 'Klíčová slova:');
$form->addTextArea('body', 'Obsah stránky:')->setRequired('Zadejte prosím Obsah stránky');
$form->addSubmit('submit', 'Odeslat');
$form->onSuccess[] = callback($this, 'addFormSubmitted');
return $form;
}
public function addFormSubmitted($form)
{
$values = $form->getValues();
$form->setDefaults(array(), TRUE);
if($this->isAjax()){
$this->template->test = 'test2';
$this->invalidateControl('formular');
$this->invalidateControl('test');
}else{
$this->redirect('this');
}
}
sablona:
{block content}
{snippet test}
{$test}
{/snippet}
{snippet formular}
{control addForm}
{/snippet}
{/block}
- tomasnikl
- Člen | 137
pokdu je jquery.nette.js toto:
/**
* AJAX Nette Framwork plugin for jQuery
*
* @copyright Copyright (c) 2009 Jan Marek
* @license MIT
* @link http://nettephp.com/cs/extras/jquery-ajax
* @version 0.2
*/
jQuery.extend({
nette: {
updateSnippet: function (id, html) {
$("#" + id).html(html);
},
success: function (payload) {
// redirect
if (payload.redirect) {
window.location.href = payload.redirect;
return;
}
// snippets
if (payload.snippets) {
for (var i in payload.snippets) {
jQuery.nette.updateSnippet(i, payload.snippets[i]);
}
}
}
}
});
jQuery.ajaxSetup({
success: jQuery.nette.success,
dataType: "json"
});
tak ano.. zalinkovani VSECH JS jsem uz zkousel.. dokonce jsem zkousel odebrat vsechny JS ktere nesouvisi s ajaxem a s nette a take to nepomohlo..
jeste me napada, jeslti nemuze byt problem v zanorenych snippetech (ale ty uz jsem take zkousel odebrat).
mam v sablone @layout.latte neco takoveho:
<div class="content left">
{snippet content}
{include #content}
{/snippet}
</div>
a sablona zminena v predchozim prispevku se includuje jako content.. takze vpodstate je tam neco takoveho:
{snippet content}
{snippet formular}
komponenta pro vykresleni formulare
{/snippet}
{/snippet}
jelikoz cela aplikace je zamyslena ajaxove, to znamena ze pri kliknuti na polozku v menu se ajaxem prekresli snippet content na pozadovanou stranku a toto obstarava metoda beforeRender v presenteru:
public function beforeRender()
{
parent::beforeRender();
if($this->isAjax())
{
$this->invalidateControl('content');
}
}
// a zde nasleduje zbytek presenteru, ktery je zminen v mem predchozim prispevku
- tomasnikl
- Člen | 137
ted jsem jeste overoval invalidaci snippetu na jine strance (stejny presenter). Tam mam vypis dat z databaze a strankovani. Strankovani je resene ajaxem, takze kdyz kliknu na „stranka 1“ tak se mi dany snippet prekresli, takze jak tak koukam, tak mi to funguje, jen u formulare s tim je problem
Editoval tomasnikl (23. 9. 2011 19:06)
- tomasnikl
- Člen | 137
tak jeste jedna vec:
vypnul jsem ajaxove odesilani a vypnul jsem redirect po odeslani a trochu
upravil kod. Predpokladam, ze by to po odeslani formulare melo nastavit prazdne
hodnoty formulare a pote je vypsat na stranku (dump).. ovsem po odeslani
formulare me to jeho hodnoty nevymaze a na stranku mi to vyprskne hodnoty, ktere
jsem do formulare zadal.. takze chyba bude asi zde
public function addFormSubmitted($form)
{
$values = $form->getValues();
$form->setDefaults(array(), TRUE);
dump($form->getValues());
if($this->isAjax())
{
$this->template->test = 'test2';
$this->invalidateControl('formular');
$this->invalidateControl('test');
}else{
//$this->redirect('this');
}
}
- tomasnikl
- Člen | 137
no to bych asi zatim neresil.. ja jsem ten snippet content uz zkousel smazat a nenacitat stranky ajaxem..
ale ted mozna spatne chapu.. ja myslel ze takoveto reseni je spravne.. kdyz budu predpokladat, ze mam sablonou @layout.latte ve ktere mam:
<html>
<head>
</head>
<body>
{include #content}
</body>
</html>
a pote mam presenter PagesPresenter.php kde mam napr:
renderDefault(){
//...... nejaky kod
}
a samozrejme sablonu templates/Pages/default.latte a v ni:
{block content}
{snippet nejakySnippet}
napr formular ve snippetu ktery po ajaxu prekreslim
{/snippet}
{/block}
Toto je spatne reseni? Ja myslel ze takto by se weby v nette mely „stavet“, nebo lepe reseno, ze takto je zamysleno pouziti blocku..
//edit:
k tomu redirectu.. tim ze redirectnu tak je mi jasne ze hodnoty formulare
ztratim.. ale myslel jsem ze kdyz nastavim formulari „prazdne“ hodnoty a
pote je zkusim vypsat tak by logicky mely byt „prazdne“..
chapu to jako:
<?php
// vypise hodnota = 1
$array = array('hodnota' => 1);
print_r($array);
//nevypie nic (toto chapu jako zminene vymazani hodnot formulare bez redirectu)
$array = array('hodnota' => 1);
$array = array();
print_r($array);
//nevypie nic
$array = array('hodnota' => 1);
header('location: jina-stranka-kde-budu-chtit-vypsat_print_r($array()).php');
print_r($array);
?>
Nebo se zmineny kod v predchozim prispevku s prepsanim hodnot chova jinak nez takto?
Editoval tomasnikl (23. 9. 2011 19:28)
- tomasnikl
- Člen | 137
aha, uz ti asi rozumim.. ja jsem to spise spatne vysvetlil, v sablone @layout.latte mam:
{snippet content}
{include #content} <!-- includuju block content ne snippet -->
{/snippet}
a v sablone pro nejakou stranku mam:
{block content}
{snippet formular}
formular
{/snippet}
{/block}
takze se neincluduje snippet ale block ve kterem je az snippet… nestastne pojmenovani bloku „content“ a snippetu „content“ asi mate
- tomasnikl
- Člen | 137
prave ze ne, jak jsem uz psal, ten obalovy snippet jsem odstranil a celou tu funkcnost s jeho invalidaci jsem z kodu take dal pryc (zakomentoval). A nefunguje to i tak… Ale jak jsem psal, i kdyz tam ten obalovy snippet je, tak mi to na jine strance funguje (jak jsem jiz znimoval, neni na te strance sice pouzit formular, ale ajaxove odkazy..)
- tomasnikl
- Člen | 137
asi spravne nechapu jak to funguje… Kdyz kliknu na odeslat formular tak se odesle ajaxovy pozadevek. Dostanu se do metody addFormSubmitted a v ni nastvim formulari defaultni hodnoty rovny prazdnemu poli. Jinymi slovy formular vyprazdnim. Ale kdy nette odesle zpet json s obsahem snippetu? v metode addFormSubmitted? protoze se mi zda ze na to jdu nejak spatne.. zda se mi, ze nette odesle json s obsahem snippetu uz drive nez ja vyprazdnim formular.
- bojovyletoun
- Člen | 667
odešleš formulář → což presenter vyhodnotí jako signál pro komponentu formuláře → formulář si sám obslouží signály → fireEvents() → zavolají se callbacky na tlačítku (onSuccess[]) → tvoje funkce nastaví formuláři prázdné hodnoty ( + ještě je nutné nvaLidateCOntrol), nedojde ke přesměrování → vykresluje se stejné stránka → jedná se o ajaxový požadavek → šablona najde jen části, které se musí překreslit a uloží je do payloadu presenteru, ten je pak pošle v JSONU.