Jakošetřit aby se formulář nezobrazoval po odeslání?

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

Jak jednoduše ošetřit aby se formulář nezobrazoval po odeslání ?

Jde o to ze kliknu na tlacitko odeslat formular a chci aby se vypsalo jen flashmessage s potvrzenim o odeslani formulare … flashmessage se mi odesle ale formular samozrejme zustava zkousel jsem to resit nejakou pomocnou promennou showform ale zasekl jsem se na tom v ktere casti presenteru muzu defaultne prednadstavit show na true a ve ktere nastavit na false…

jedna se urcite o prkotinu jen si jeste s tim nettem netykam…

Editoval pjoter (24. 8. 2009 23:42)

ic
Člen | 430
+
0
-

Má to být jako že po odeslání formuláře se zobrazí ten samý naplněný stejnými daty? Nebo chceš docílit odeslání formuláře bez nutnosti obnovení stránky?

pjoter
Člen | 118
+
0
-

po odeslani se mi prave zobrazi ten samy vyplneny a flashmessage s informaci o uspesnem odeslani formulare jenze ja tam ten formular nechci chci tam pouze tu zpravu…

Panda
Člen | 569
+
0
-

Co něco takového:

{if !$presenter->hasFlashSession()}
	{control myForm}
{/if}

Tzn. zobrazit formulář jen v případě, že $presenter->hasFlashSession() vrátí FALSE – když není nastavena žádná flash zprávička (pozor: budou se počítat i „špatné“ (tzn. při chybě) flash zprávičky, ale při odeslání formuláře se chyby budou dávat spíš jako errory k samotnému formuláři).

Etch
Člen | 403
+
0
-

A proč tam nedáš redirect na jinej action? Nebo opravdu nutně potřebuješ po odeslání formu zůstat na stejné action?

pjoter
Člen | 118
+
0
-

Snazim se na to prijit vim ze to tu je rozebrane ve vice topicich ale porad se mi zobrazuje ten formular… misto redirectu mi to vypise to url na ktere se to ma presmerovat do flashmessage :(

<?php


require_once dirname(__FILE__) . '/BasePresenter.php';


class RegisterPresenter extends BasePresenter
{
	protected function createComponentForm()
	{
		class_exists('Captcha');

		// soubor s použitým písmem
		Captcha::$defaultFont = '%appDir%/fonts/Vera.ttf';

		// velikost fontu pro písmena v obrázku
		Captcha::$defaultFontSize = 30;

		// počet písmen v obrázku
		Captcha::$defaultLength = 5;

		// šířka obrázku v pixelech
		Captcha::$defaultWidth = 150;

		// výšku obrázku svěříme autodetekci
		Captcha::$defaultHeight = 0;

		// černý text
		Captcha::$defaultTextColor = Image::rgb(0, 0, 0);

		// na bílém pozadí
		Captcha::$defaultBgColor = Image::rgb(255, 255, 255);

		// v případě AppForm nastavíme masku odkazu na presenter obrázků
		Captcha::$defaultLinkMask = 'Captcha:show';


		$form = new AppForm($this, 'form');

		// setup custom rendering
		$renderer = $form->getRenderer();
		$renderer->wrappers['form']['container'] = Html::el('div')->id('form');
		$renderer->wrappers['form']['errors'] = FALSE;
		$renderer->wrappers['group']['container'] = NULL;
		$renderer->wrappers['group']['label'] = 'h3';
		$renderer->wrappers['pair']['container'] = NULL;
		$renderer->wrappers['controls']['container'] = 'dl';
		$renderer->wrappers['control']['container'] = 'dd';
		$renderer->wrappers['control']['.odd'] = 'odd';
		$renderer->wrappers['control']['errors'] = TRUE;
		$renderer->wrappers['label']['container'] = 'dt';
		$renderer->wrappers['label']['suffix'] = ':';
		$renderer->wrappers['control']['requiredsuffix'] = " \xE2\x80\xA2";



		$form->addGroup();
		$form->addText('jmeno', 'Jméno:', 32)
			->addRule(Form::FILLED, 'Zadejte jméno.');

		$form->addText('prijmeni', 'Příjmení:', 32)
			->addRule(Form::FILLED, 'Zadejte příjmení.');

		$form->addText('telefon', 'Telefon:', 13);

		$form->addGroup();
		$form->addText('email', 'Email:', 35)
			->addCondition(Form::FILLED)
			->addRule(Form::EMAIL, 'Zadali jste neplatný email.');

		$form->addPassword('heslo', 'Heslo:')
			->addRule(Form::FILLED, 'Zadejte heslo.');

		$form->addPassword('hesloCheck', 'Potvrzení hesla:')
			->addRule(Form::FILLED, 'Zadejte potvrzovací heslo.')
				->addConditionOn($form['hesloCheck'], Form::FILLED)
					->addRule(Form::EQUAL, 'Hesla se musí shodovat !', $form['heslo']);

		$form->addGroup();
		$form->addCaptcha('captcha', 'Opište bezpečnostní kód: ')
			->setTextColor(Image::rgb(0, 0, 0))
				->addRule('Captcha::validateValid', 'Opište správně písmena z obrázku.');

		$form->addGroup();
		$form->addSubmit('submit1', 'Registrovat se')->onClick[] = array($this, 'okClicked');

		return $form;
	}

	public function okClicked(SubmitButton $form)
	{

		$values = $form->form->getValues();
		try {
			// Zpracování
			unset($values['hesloCheck']);
			unset($values['captcha']);
			unset($values['captcha__key']);
			$values['heslo'] = sha1($values['heslo']);

			$this->db->query('INSERT INTO uzivatele', $values);

			$this->getPresenter()->flashMessage('Registrace proběhla úspěšně.','success');
			$this->redirect('finish');

		} catch(Exception $e){
			$this->getPresenter()->flashMessage($e->getMessage(),'failure');
		}

	}

	public function renderFinish() {
		$this->template->form = '';
	}

}
?>
kravčo
Člen | 721
+
0
-

Volanie Presenter::redirect() vyhadzuje výnimku RedirectingException, ktorú používa Nette interne na obsluhu presmerovaní. Ty ju v svojom kóde zachytávaš pomocoucatch (Exception $e), čo nie je správne (a Nette to znemožnuje vykonať presmerovanie). Ak chceš ošetrovať výnimky spôsobené databázou (to predpokladám), odchytávaj iba DibiDriverException a iba na volaní databázy:

public function okClicked(SubmitButton $form)
{
    $values = $form->form->getValues();
    // Zpracování
    unset($values['hesloCheck']);
    unset($values['captcha']);
    unset($values['captcha__key']);
    $values['heslo'] = sha1($values['heslo']);

    try {
        $this->db->query('INSERT INTO uzivatele', $values);
        $this->flashMessage('Registrace proběhla úspěšně.', 'success');
    } catch (DibiDriverException $e){
        $this->flashMessage('Registrace se nezdařila. Zkuste ji, prosím, opakovat později.', 'failure');
        MyTools::handleDbException($e);
    }

    $this->redirect('finish');
}

Navyše, správa výnimky nie je práve to, čo by mali bežní používatelia vidieť, môže obsahovať citlivé údaje a veci neznalým aj tak nič nepovie…

DocX
Člen | 154
+
0
-

//mělo by se tu udělat nějaké AJAXové upozornění na nové příspěvky během psaní nového :)

Jen vysvětlím pár drobností, které tam měl:

  • $this->getPresenter()->... je nesmysl, protože už přece jsi ve třídě presenteru. Stačí proto jen $this->flashMessage(). Jiné by to bylo, kdyby jsi tuto metodu měl ve vlastní komponentě.
  • To vynulování $this->template->form = '' v renderFinish mi přijde také zbytečné, protože na view Finish budeš mít vlastní soubor šablony a v něm žádný form vůbec nemusíš mít ;)

Editoval DocX (25. 8. 2009 13:28)

pjoter
Člen | 118
+
0
-

jj chtel jsem osetrit databazi … fakt v tom docela plavu mohl bys mi prosim poradit jak by mel ten mytools vypadat ?

Editoval pjoter (25. 8. 2009 13:29)

DocX
Člen | 154
+
0
-

pjoter napsal(a):

jj chtel jsem osetrit databazi akorat mi to ted hlasi neexistujici objekt mytools co presne je a kde se to da sehnat ? nebo to mam jen to nemam nekde naimportovane ?

To byl příklad ;) Mělo to naznačit, že si můžeš vytvořit vlastní knihovnu nějakých pomocných funkcí, kde by mohla být právě tato, ošetřující vyjímky databáze (například zapsááním do logu) ;)

Nemusí tam být také nic, pak ale jen uživateli vypíšeš, že se to nezdařilo, ale ty nikde nebudeš mít zaznamenané, že někdy nastala nějaká chyba.

A do třetice xD: Můžeš místo toho pužít Debug::processException($ex), což je funkce laděnky v Nette, která právě vyjímku pouze zaznamená do logu (když je nastavený)

Editoval DocX (25. 8. 2009 13:32)

pjoter
Člen | 118
+
0
-

Abych to uzavřel tak jsem to zobrazování formuláře nakonec vyřešil takto:

<?php
	public function actionDefault()
	{
		$form = $this['form'];
		$this->template->formShow = TRUE;
		if($form->isSubmitted())
		{
			$this->template->formShow = FALSE;
		}
	}
?>
Panda
Člen | 569
+
0
-

pjoter napsal(a):

Abych to uzavřel tak jsem to zobrazování formuláře nakonec vyřešil takto:

<?php
	public function actionDefault()
	{
		$form = $this['form'];
		$this->template->formShow = TRUE;
		if($form->isSubmitted())
		{
			$this->template->formShow = FALSE;
		}
	}
?>

Pozor na validaci a zpracování dat, pokud dojde k nějakým chybám, tak toto řešení uživateli chyby neukáže. Doporučuji ještě do podmínky přidat !$form->hasErrors().

pjoter
Člen | 118
+
0
-

Jj určitě díky za radu