Manuálne vykreslenie – ako po chybe zachovať obsah polí

- pseudonym
 - Člen | 57
 
Dobrý deň,
vykresľujem si sám napr. kontaktný formulár a chcem sa opýtať, ako sa dá
zabezpečiť aby po odoslaní pri vypísaní chybných polí sa nevymazali aj
tie, ktoré chybné nie sú. Resp. chcem aby hodnoty ostali vo všetkých
poliach a aby sa len vyznačili tie, ktoré sú chybné.
ContactForm.php:
<?php
use Nette\Application\UI,
    Nette\ComponentModel\IContainer;
class ContactForm extends UI\Form
{
    public function __construct(IContainer $parent = NULL, $name = NULL)
    {
        parent::__construct($parent, $name);
        $this->addText("name", "Vaše meno *")
            ->setRequired("Prosím, vyplnte Vaše meno.")
            ->addRule($this::PATTERN, "Prosím, vyplnte Vaše meno.", "^((?!Vaše meno *).)*$");
        $this->addText("email", "Váš e-mail *")
            ->addRule($this::EMAIL, "Prosím, vyplnte váš e-mail.");
        $this->addTextArea("message")
            ->setRequired("Prosím, vyplnte Vašu správu.");
        $this->addSubmit("send", "Odoslať e-mail");
    }
}
?>
Presenter:
<?php
protected function createComponentContactForm($name) {
        $form = new \ContactForm();
        $form->onSuccess[] = callback($this, 'contactFormSubmitted');
        return $form;
    }
    public function contactFormSubmitted($form)
    {
        $values = $form->getValues();
        $this->template->values = $values;
    }
?>
Šablona:
{form contactForm}
<ul class="errors" n:if="$form->hasErrors()">
    <li n:foreach="$form->errors as $error">{$error}</li>
</ul>
<form id="contactform" action="" method="post" class="botspacer-20" n:syntax="double">
    <ul class="cform">
        <li class="required">
            <input class="form_input" type="text" name="name" id="name" value="Vaše meno *" onblur="if(this.value==''){this.value='Vaše meno *'}" onfocus="if(this.value=='Vaše meno *'){this.value=''}" />
        </li>
        <li class="required">
            <input class="form_input" type="text" name="email" id="email" value="Váš e-mail *" onblur="if(this.value==''){this.value='Váš e-mail *'}" onfocus="if(this.value=='Váš e-mail *'){this.value=''}" /><div class="validation"></div>
        </li>
        <li class="required">
            <textarea class="form_textarea" rows="10" cols="62" name="message" id="message"></textarea>
        </li>
        <li class="center">
            <input type="submit" value="Odoslať správu" class="button" name="Submit" />
        </li>
    </ul>
</form>
{/form}
Poprípade ak mi niekto vie povedať čo robím zle…
Vopred ďakujem za odpovede.
PS: Skúšal som to hľadať, ale nenašiel som nič podobné. Ťažko hľadať niečo, čo neviem nijako nazvať.

- Vojtěch Dobeš
 - Gold Partner | 1316
 
Moc nerozumím té šabloně. Proč tam vypisuješ přímo ručně HTML formulářové prvky? Manuální vykreslování formuláře znamená použití formulářových maker. Šablona by tedy měla být:
{form contactForm class => "botspacer-20"}
<ul class="errors" n:if="$form->hasErrors()">
    <li n:foreach="$form->errors as $error">{$error}</li>
</ul>
    <ul class="cform">
        <li class="required">
            {input name class => "form_input"}
        </li>
        <li class="required">
            {input email class => "form_input"} <div class="validation"></div>
        </li>
        <li class="required">
            {input message class => "form_textarea", rows => "10", cols => "62"}
        </li>
        <li class="center">
            {input name Submit}
        </li>
    </ul>
{/form}
Dále:
- To, oč se tam snažíš těmi javascriptovými atributy, by mnohem snáze
	řešil placeholder:
		
$form->addText(..., ...)->setEmptyValue('Váš email');resp.
$form->addText(..., ...)->setAttribute('placeholder', 'Váš email'); - Úplně ti tam chybí labely: 
{label email /}atd. 
Doporučuju si pročíst dokumentaci: https://doc.nette.org/cs/forms#…, je to tam docela bohatě popsané ;)
Editoval vojtech.dobes (11. 4. 2012 10:47)

- pseudonym
 - Člen | 57
 
Ďakujem za odpoveď.
Keď to budem mať pomocou tých makier, budú sa mi uchovávať zadané hodnoty
po reloadnutí formulára?
Mám na mysli toto:
odošlem formulár, kde zadán mamiesto e-mailu napr. „xyz“, formulár sa
načíta znova s tým, že vypíše, kde je chyba. Pri mojom riešení mi
zmiznú vyplnené dáta z formulára – teda ak som mal napr. správne
vyplnené meno, tak to zmizne. Chcem, aby sa tieto hodnoty uchovávali, teda aby
polia formulára ostali vyplnené.
Čo sa týka tých makier a placeholdera, skúsim to tak prerobiť. Čo sa týka labelu, ten tam nechcem, práve preto tam je ten javascript/placeholder.
EDIT: Super vec, už to funguje, keď použijem tie makrá. Ďakujem pekne :-)
Editoval pseudonym (11. 4. 2012 10:57)

- ViPEr*CZ*
 - Člen | 822
 
pseudonym napsal(a):
Ďakujem za odpoveď.
Keď to budem mať pomocou tých makier, budú sa mi uchovávať zadané hodnoty po reloadnutí formulára?
Ano, respektive pokud se pošle submit a ten bude nevalidní podle zadaných pravidel formuláře, form vrátí error a vyplněné prvky zůstanou zachované.
Editoval ViPEr*CZ* (11. 4. 2012 10:58)

- Vojtěch Dobeš
 - Gold Partner | 1316
 
<label> je fajn už kvůli přístupnosti (čtečka
nějaké javascriptové udělátko nepochopí, label však ano) – kdyžtak ho
tam umísti a (ne pomocí display:none) vizuálně skryj, ale ať
je v kódu stránky přítomný.
Jinak aby se tam vypsaly odeslané hodnoty, to všechno Nette formuláře samozřejmě řeší :) Tys je ale úplně obešel – ve skutečnosti jsi nevypisoval ten nadefinovaný formulář, ale nesouvisející HTML kód.

- pseudonym
 - Člen | 57
 
Viem na čo je dobrý label, rád ho používam, ale jednoducho mám vopred preddefinovanú šablonu (skúsim tam ten label dať s tým, že ho skryjem).
Čo sa týka „placeholder“, funguje báječne, len teraz keď mám vo formulári chybu, nevypíše sa mi zoznam nad formulárom ako som to mal doteraz,
<ul class="errors" n:if="$form->hasErrors()">
    <li n:foreach="$form->errors as $error">{$error}</li>
</ul>
ale vyskakujú mi JS alerty. Dá sa toto ešte nejako ošetriť?

- Vojtěch Dobeš
 - Gold Partner | 1316
 
Máš nalinkovaný netteForms.js? Jestli jo, tak ti
s použitím těch maker konečně začal fungovat :) Tedy zprovoznila se ti
klientská validace, ta serverová samozřejmě funguje taky, ale vlastně se
k ní ani nedostaneš. Zkus ten skript odlinkovat (zakomentovat), a dojde na
serverovou validace – a hlášky by se měly vypsat.

- pseudonym
 - Člen | 57
 
Odlinkoval som netteForms.js. Teraz mi to vypisuje krásne
hlášky – bublinka s výkričníkom a textom „Please fill in this
field.“. Stále ale nefunguje ten zoznam, kde chcem vypísať chyby.
Zistil som, že tie „bublinky“ vypisuje len pri poliach, ktoré sú
->setRequired(). Ešte sa s tým skúsim pohrať.
Editoval pseudonym (11. 4. 2012 11:26)

- Vojtěch Dobeš
 - Gold Partner | 1316
 
Tak to už nevím… no jistě, to je nativní validace prohlížeče.
Odstraň si ta volání setRequired() a nechej jenom
addRule(....
Nicméně si nedokážu představit – čemu by měla klientská validace vadit :) (tudíž ve finále bych netteForms přilinkované nechal).
Editoval vojtech.dobes (11. 4. 2012 11:27)

- ViPEr*CZ*
 - Člen | 822
 
Ty bubliny dělá html5… jde o klientskou validaci… to je normální
dělat validaci u klienta a neobtěžovat server a kvůli zlobivým
uživatelům se musíme ještě obtěžovat se serverovou, ale to dělá nette
za Vás… a ten seznam vypisuje. Jen Vy k tomu přistupujete jako hodný
klient a tak neobejdete klientskou validaci.
Snad nějakým js si dát tu práci a odebrat ony attributy html5
required=„required“, ale nedělal bych to.

- ViPEr*CZ*
 - Člen | 822
 
pseudonym napsal(a):
Nuž, je to v Chrome (tie bublinky). Skúsil som to v Internet Destroyer-i a tam to funguje bez problémov. Ok, takže už viem kam sa budú uberať ďalšie query pre Google ;-)
Ešte raz veľmi pekne ďakujem za pomoc :-)
Bubliny jsou zkrátka tam kde je tento attribut podporován :-)