Zobrazení errorů u přihlašovacího formu, při odeslání téhož formu odjinud

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

Zdravím,
nedaří se mi vypsat errory u přihlašovacího formuláře.
Přihlašovací formulář mám v menu po vyjetí (jméno, heslo, submitButton) – tady nechci errory zobrazovat, vykresluji přes

<form n:name="signInForm" action="{plink Sign:in}" method="post" class="dropdown-menu well">
    <div class="form-group">
        <input type="text" class="form-control" n:name="username" placeholder="Jméno">
    </div>
    <div class="form-group">
        <input type="password" class="form-control" n:name="password" placeholder="Heslo">
    </div>
    <div class="form-group">
        <label>Trvalé přihlášení <input type="checkbox" n:name="remember"></label>
    </div>
    <div class="text-center row">
        <button type="submit" class="btn btn-primary">Přihlásit</button>
    </div>
</form>

V případě chyby nechám zobrazit Sign:in, kde mám {control signInForm}.
Komponentu vytvářím v BasePresenteru:

protected function createComponentSignInForm() {
    $form = new SignInForm();

    $form->setUser($this->user); // kvůli nastavení expirace, možná přesunu do autentizátoru

    return $form;
}

Otázka teda zní: proč se mi nezobrazujou errory při odeslání formu z menu?

David Matějka
Moderator | 6445
+
0
-


chyby musis vykreslit, bud vsechny pomoci

{$form->render('errors')}
//nebo rucne
{foreach $form->errors as $error}
{$error}
{/foreach}

nebo pro jednotlive inputy

<div class="error" n:if="$form['username']->hasErrors()">{$form['username']->error}</div>

sorry, neprecet jsem si to uplne cele.
Je problem, ze prepisujes action, tudiz tam chybi ?do=signInForm-submit, tak tam pripoj tenhle parametr rucne

<form .. action="{plink Sign:in do=>signInForm-submit}">

neni to teda uplne nejcistci reseni, ale nevim, jestli existuje alternativa

Editoval matej21 (25. 8. 2014 21:39)

CZechBoY
Člen | 3608
+
0
-

No to by mělo nette vykreslit samo, když tam dám {control signInForm} ne?
Právě, že mi to vykresluje, když ale odešlu form ze stránky Sign:in. Když odešlu z menu tak už nevykreslí.

To nejde nějak udělat duplicitní form, abych zobrazil errory v jiný šabloně?

David Matějka
Moderator | 6445
+
0
-

@CZechBoY nevim, jestli sis vsimnul – ten prispevek jsem upravil (tesne pred tim, nez si poslal ty ten komentar)

CZechBoY
Člen | 3608
+
0
-

Jde teda nějak ručně vykreslit form takhle přes <form n:name> a nevypisovat třeba action vůbec?
Když ve formu ručně nevypíšu action, tak mi to hodí akci „/“, což teda asi moc nepomůže.

Nebo jde nějak jednoduše vykreslit form bez labelů? To je totiž asi jediná změna oproti „full“ verzi přihlašovacího formu.

David Matějka
Moderator | 6445
+
0
-

kecam, vlastne ani neni nutno nastavovat to ?do..., ted se ten do parametr dava do POST dat. Tak ted nevim, cim to je.. to prvni by mozna melo fungovat – mozna zkus smazat method a action nastav v presenteru a ne takhle ve vypise…

CZechBoY
Člen | 3608
+
0
-

Nevim jak se to dělá… vytvářim form normálně přes new UI\Form.
Nejde to ani s do ani bez :(
Ani když dám pryč method tak to nepomáhá, nicméně odteď si ušetřím psaní method=„post“ :D
Action jsem nastavil v BasePresenteru:

protected function createComponentSignInForm() {
    $form = new SignInForm();

    $form->setAction($this->link('Sign:in'));

    $form->setUser($this->user);

    return $form;
}

ale pořád se v šabloně vypisuje action=„/“ (asi protože jsem na homepage, ale ten form by měl fungovat z každý stránky potom)

Nějaký další nápady?

Tirus91
Člen | 199
+
0
-

@CZechBoY
dej pryč

$form->setAction($this->link('Sign:in'));

a action ani nevykreslu. Nette si ho doplní samo
a v latte to nech takto

<form n:name="signInForm" class="dropdown-menu well">
David Kudera
Člen | 455
+
0
-

V první chvíli jsem chtěl napsat, že rada od @Tirus91 je celkem k ničemu, když potřebuješ chyby zobrazit někde jinde než na tom samým formu. Ale nakonec proč ne.. Co nechat prostě action opravdu vypsat samotným nette? Pak v onSuccess by jsi měl přihlášení, ale v případě chyby se ti přidala flashMessage na presenter s tou chybou a pak bylo samotné přesměrování na Sign:in, kde se ty flashMessages taky vykreslelují


Jo vlastně by to předání chyb muselo být i v onError, aby to šlo i na validační hlášky a ne jen na ty jako „uživatel nebo heslo je chybné“..

David Matějka
Moderator | 6445
+
0
-

zkusil jsem to s tim nastavenim action v presenteru a funguje mi to ok. Na strance, kde mam „lite“ verzi formu a odeslu, tak se to presmeruje na „full“ verzi a zobrazi se errory. Jakou mas verzi nette?

CZechBoY
Člen | 3608
+
0
-

Nette 2.2.2
Ještě teda pošlu komplet komponentu.

class SignInForm extends BSForm {

	/**
	 * @var \Nette\Security\User
	 */
	private $user;

	/**
	 * @var \App\Model\UserManager
	 */
	private $userManager;

	/**
	 * Sign-in form factory.
	 */
	public function __construct($bla = null, $bla2 = null)
	{
		parent::__construct($bla, $bla2);

		$this->addText('username', 'Uživatelské jméno:')
			->setRequired('Vložte uživatelské jméno.');

		$this->addPassword('password', 'Heslo:')
			->setRequired('Vložte heslo.');

		$this->addCheckbox('remember', 'Trvalé přihlášení');

		$this->addSubmit('login', 'Přihlásit');

		$this->addProtection('Ověření vypršelo. Odešlete formulář znovu.');
		$this->onSuccess[] = $this->signInFormSucceeded;
	}

	/**
	 * @param \Nette\Security\User
	 */
	public function setUser(Nette\Security\User $user) {
		$this->user = $user;
	}

	/**
	 * @param \Kdyby\BootstrapFormRenderer\BSForm $form
	 * @param array $values
	 */
	public function signInFormSucceeded(BSForm $form, $values)
	{
		if ($values->remember) {
			$this->user->setExpiration('14 days', FALSE);
		} else {
			$this->user->setExpiration('20 minutes', TRUE);
		}

		try {
			$this->user->login($values->username, $values->password);

			$this->presenter->flashMessage('Přihlášeno.', 'success');

			$this->presenter->redirect('Homepage:');

		} catch (Nette\Security\AuthenticationException $e) {
			$form->addError($e->getMessage());
		}
	}

}

ano, bez action jsme to už zkoušeli a hodí to úplně stejnou cestu „/“.

Musím teda nějak ručně přidávat errory ve validate metodě?

CZechBoY
Člen | 3608
+
0
-

Našel někdo nějakej problém v tom mým kódu?
Jiný řešení?

David Matějka
Moderator | 6445
+
0
-

@CZechBoY divny, nemuzu tu chybu nasimulovat. Action se mi nastavi spravne…

protected function createComponentSignInForm() {
    $form = new SignInForm();
    $form->setAction($this->link("..."));
    $form->setUser($this->user);

    return $form;
}

slo by nekam (na gh nebo aspon do zipu) hodit ten projekt (nebo jeho podstatny casti)?

iguana007
Člen | 970
+
0
-

A co ten konec definice formu změnit takto? To by nešlo/nepomohlo?

		$this->onSuccess[] = array($this, "signInFormSucceeded");
		$this->onError[]   = array($this, 'invalidSubmit');

		return $this;
	}

	public function invalidSubmit(Form $form)
	{
		foreach ($form->errors as $error) {
			$this->presenter->flashMessage($error, 'error');
		}
	}
CZechBoY
Člen | 3608
+
0
-

Aha, ono jde asi o to, že vytvářim novej form ještě v komponentě menu.
Zkráceně na gitu: https://github.com/…sign-in-form

CZechBoY
Člen | 3608
+
0
-

Vykoumali jste něco z toho gitu?

David Matějka
Moderator | 6445
+
0
-

tak ta akce jde zmenit bez problemu

$form->setAction($this->presenter->link("Sign:in"));

pridany sem

problem je – jak rikas – ze to mas v komponente. Po odeslani se na te sign in strance nic nezobrazi, jelikoz je to uplne jinej formular (jina instance v jine casti stromu komponent)

CZechBoY
Člen | 3608
+
0
-

Takže mám udělat singleton jo? Okej zkusim, kdyžtak edituju.

David Matějka
Moderator | 6445
+
+1
-

ne, singlenton nepomuze (a zpusobi dalsi problemy). hlavni problem je umisteni ve stromu komponent – ze jednou je to primo pod presenterem a jednou pod komponentou..

slo by teoreticky krom nastaveni action v tom formu pod komponentou taky zmenit hodnotu hidden fieldu „do“, aby ta hodnota byla stejna jako ve formu pod presenterem.

nebo si v te komponente vytahni ten form z presenteru, nejak takhle: $this->presenter['signInForm']. to pak predej do sablony komponenty a vykresli pres {form $form}

Editoval matej21 (29. 8. 2014 21:34)

CZechBoY
Člen | 3608
+
0
-

Jo, už to jde, díky.

Finální řešení:
BasePresenter

	protected function createComponentSignInForm() {
		$form = new SignInForm();

		$form->setAction($this->link('Sign:in'));

		$form->setUser($this->user);

		return $form;
	}

Komponenta:

	public function render() {
		$this->template->form = $this->presenter->getComponent('signInForm');
	}

Šablona komponenty:

<form n:name="$form" class="dropdown-menu well">...</form>