Neuspěšná validace formuláře – skok na kotvu
- Gruid
- Člen | 25
Ahoj, mám v komponentě form:
protected function createComponentAnswersAddForm() {
$form = new Form;
$form->addText('subject', 'Předmět:', 50, 50)
->addRule(Form::FILLED, 'Zadej předmět');
$form->addTextarea('content', 'Text:', '50', 4)
->addRule(Form::FILLED, 'Zadej text');
$form->addSubmit('save', 'Odeslat příspěvek');
$name = $form['save']->getControlPrototype(); // htmlObject controlu
$name->class .= ' brown';
$form->onSuccess[] = callback($this, 'answersAddFormSubmitted');
return $form;
}
// Callback pro přidání příspěvku
public function answersAddFormSubmitted($form) {
$form->setAction .= '#answers';
try {
// Zapíšeme řádek s akcí
$values = $form->values;
$values['author'] = $this->user;
$values['thread'] = $this->thread;
$values['date%sql'] = 'NOW()';
dibi::query('INSERT INTO answers ', $values); //, ' ON DUPLICATE KEY UPDATE %a', $values);
$flash = $this->flashMessage("Data byla úspěšně uložena", 'success');
$this->presenter->redirect($this->presenter->view . '#answers');
} catch(DibiDriverException $e) {
$this->flashMessage($e->getMessage(), "error");
}
}
Pokud neprojde validace formu, chtěl bych, aby se stránka nejen znovu načetla, ale také skočila na kotvu #answers. Našel jsem na fóru asi dvě vlákna, ale nic mi nefungovalo ($form->action .= ‚#answers‘;) Děkuju za radu. Nette 2.0 PHP 5.2
Editoval Gruid (24. 6. 2011 9:10)
- Gruid
- Člen | 25
Javascriptovou validaci nepoužívám, takže se stránka reloaduje a
vypíše chyby nad formulářem. Jestli vše dobře chápu, bude stačit
nějakej trik, kdy se při reloadu stránky přídá za URL #kotva. Když mi
projde callback u formu, tak si nastavim přeci třeba:
$this->redirect('Neco:seznam#kotva');
Tak předpokládám, že
URL při tom reloadu, kterej proběhně, aby mi vypsal třeba: „Zapomněl jste
vyplnit e-mail“, musí jít taky nějak ovlivnit a přimlasknout za něj tu
kotvu. Nebo ne?
- uestla
- Backer | 799
Špatně jsem Gruidův problém pochopil – už chápu, že mu jde o to v action formuláře směřovat na kotvu, ve které se případně uvedou chyby – když ne, tak zase na kotvu, ve které se zobrazí flash message o úspěšnosti…
Nicméně nic jsem nezkoušel, ani netestoval, šlo mi jen o rozbor :-)
Každopádně, pokud používáš PHP 5.2, jak píšeš, v Presenteru
zásadně používej AppForm
, přičemž následující by mělo
fungovat (testoval jsem sice pro 5.3, ale v Nette 2.0b):
// EDIT 2: refactoring
protected function createComponentAnswersAddForm($name)
{
$form = new AppForm($this, $name);
$form->action .= '#mojekotva';
}
Čili když nebude formulář při odeslání úspěšně validován, neproběhne ani přesměrování a stránka zůstane „viset“ na URL jak se signálem, tak s kotvou.
EDIT:
Dnes jsem hodně zpomalený, chápal jsem to, že se nepodařilo onu kotvu do action nastavit… V tom případě pardon, neumím poradit :(
Editoval uestla (27. 6. 2011 13:15)
- uestla
- Backer | 799
Když už jsme tedy u toho, tak jsem se rozhodl to v tom IE vyzkoušet – a popravdě nevím, co děláte špatně, ale mně to funguje (ať už ve form action nebo v redirectu). Kód:
Presenter:
protected function createComponentMyForm($name)
{
$form = new Nette\Application\UI\Form($this, $name);
$form->action .= '#wtd';
$form->addSubmit('send', 'Odeslat');
// zakomentuj si násl. řádek pro simulaci nevalidního vyplnění
$form->onSuccess[] = callback($this, 'myFormSubmitted');
}
public function myFormSubmitted(Nette\Application\UI\Form $form)
{
$this->redirect('this#wtd');
}
Šablona:
{block content}
<br><br><br><br><br><br><br><br><br><br>
<h2 id="wtd">What to do next?</h2>
{control myForm}
<br><br><br><br><br><br><br><br><br><br>
Napadlo mě, že třeba používáte starou a zatracovanou konstrukci
<a name="wtd"></a>
, ale i s tou mi to v IE funguje,
tak nevím…
- 22
- Člen | 1478
je fakt, že to netestuju s každou novou revizí Nette, ale teď se to zdá opravdu v pořádku, ale prisaham bohu, nebylo tomu vždycky tak.
- VaKvas
- Začátečník | 111
Zdravim,
no ja stale nedoresil toto:
Prvni redirect s # funguje a druhy ne … Podotykam, ze jen v IE .. Pouzivam
Jquery TABS… takze mozna tam bude nekde problem… tezko rict..
function formSubmitted($form) {
$values = $form->values;
if(!IsSet($values['access_only'])) $values['access_only'] = 'all';
if ($this->action === 'catEdit') {
$this->documentsModel->updateDocumentsCat($values, $this->getParam('id'));
} else {
try {
$this->documentsModel->addDocumentsCat($values);
} catch (\Exception $e) {
$form->addError($e->getMessage());
return;
}
}
$this->flashMessage('Kategorie byla ulozena');
$this->redirect('Documents:#tabs-' . $this->getParam('id'));
}
function FormDocSubmitted(Form $form) {
$values = $form->values;
if ($values['file']->getTemporaryFile()) {
$binarydata = file_get_contents($values['file']->getTemporaryFile());
$values['type'] = $values->file->getContentType();
$values['size'] = $values->file->getSize();
$values['binfile'] = $binarydata;
$values['name'] = $values->file->getName();
}
if($values['is_contract'] == null) $values['is_contract'] = '0';
$values['by'] = $this->user->identity->name;
$values['inserted'] = new \DateTime();
unset($values['file']);
if ($this->action === 'docEdit') {
$this->documentsModel->updateDocuments($values, $this->getParam('id'));
} else {
try {
$this->documentsModel->addDocument($values);
} catch (\Exception $e) {
$form->addError($e->getMessage());
return;
}
}
$this->flashMessage('Dokument byl uložen');
$this->redirect('Documents:#tabs-' . $values['category']);
}
- uestla
- Backer | 799
Přesměrovává-li se na správnou URL včetně parametru fid
pro flash zprávičky a dochází-li pouze ke ztrátě kotvy, nemělo by být
obtížné vystopovat, kde přesně se tomu tak děje – prostě si projet
životní cyklus od onoho volání redirectu a vždy na patřičném místě
vydumpovat patřičná data a hlídat, kde kotva ještě je a kde už ne. Při
projíždění zkončíš nejspíš na https://api.nette.org/…ter.php.html#613,
čili bude nejspíše ještě nutné navštívit https://api.nette.org/…ion.php.html#70
a hledat tam. Víc nejsem schopen poradit.