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

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

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 &#42;" onblur="if(this.value==''){this.value='Vaše meno &#42;'}" onfocus="if(this.value=='Vaše meno &#42;'){this.value=''}" />
        </li>
        <li class="required">
            <input class="form_input" type="text" name="email" id="email" value="Váš e-mail &#42;" onblur="if(this.value==''){this.value='Váš e-mail &#42;'}" onfocus="if(this.value=='Váš e-mail &#42;'){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
+
0
-

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:

  1. 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');
  2. Ú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
+
0
-

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

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

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

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

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

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

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

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.

pseudonym
Člen | 57
+
0
-

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

ViPEr*CZ*
Člen | 813
+
0
-

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

pseudonym
Člen | 57
+
0
-

No áno, tak som to myslel, je to v prehliadači, nie v Nette Frameworku.
Jednoducho som vypol ->setRequired() a namiesto toho som nastavil pri povinných poliach MIN_LENGTH.
K tomu HTML5 placeholder-u – všetky prehliadače okrem IE ho vykreslia, ale to už musím riešiť inak.

pseudonym
Člen | 57
+
0
-

Ešte k tomu „divnému“ javascriptu čo som používal (bol zakomponovaný v šablone, ktorú používam). Je to JS, možno nie najúžasnejšie riešenie, ale aspoň to všade funguje rovnako. S tým placeholderom to nevidím ružovo …