Neuspěšná validace formuláře – skok na kotvu

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Gruid
Člen | 25
+
0
-

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)

VaKvas
Začátečník | 111
+
0
-

Myslim, ze v IE to jen tak nepojede… V Mozille pravdepodobne ano…
Uz jsem to resil, ale nedoresil…

22
Člen | 1478
+
0
-

tak bych řekl, že jediná možnost je javascript..

uestla
Backer | 799
+
0
-

Logicky nemůžeš nastavit action formuláři v době, kdy ještě nebyl odeslán. Co ale můžeš je přesměrovat při neúspěšné validaci na danou adresu, ve které už si danou kotvu snadno uvedeš.

22
Člen | 1478
+
0
-

můžeš tedy zveřejnit funkční řešení pro IE, pokud možno i pro úspěšný submit? mně se to tedy nepodařilo v IE redirectovat na kotvu.

Gruid
Člen | 25
+
0
-

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?

22
Člen | 1478
+
0
-

kdyby to fungovalo, už by to sem kamarád uestla asi dávno poslal…

Editoval 22 (27. 6. 2011 12:08)

uestla
Backer | 799
+
0
-

Š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)

Gruid
Člen | 25
+
0
-

@uestla Díííík. To je ono. Už jsem tohle vlastně zkoušel. Nechápu, proč mi to nefungovalo. Jede to krásně. Ještě jednou děkuju.

uestla
Backer | 799
+
0
-

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
+
0
-

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.

uestla
Backer | 799
+
0
-

V pohodě, to je holt příznak bouřlivého vývoje – bůhví (ten, kterému výše přísaháš), jakou verzi jsi měl, když jsi odkazovaný příspěvek 10. května psal, každopádně dohledávat fixující commit se mi nechce ;-)

VaKvas
Začátečník | 111
+
0
-

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
+
0
-

Pod pojmem „redirect nefunguje“ si představím, že nedochází k přesměrování – bavíme se pořád o tom, že v URL kotva fyzicky je, ale prohlížeč na ni prostě jen nesjede?

VaKvas
Začátečník | 111
+
0
-

Omlouvam se…
Ve funkcnim pripade je kotva v url a funguje…
v opacnem pripade redirect funguje, ale ta kotva v url neni… i jsem se to snazil krokovat, ale neprisel jsem na to, kam zmizi…

Editoval VaKvas (27. 6. 2011 19:13)

uestla
Backer | 799
+
0
-

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.