12. díl - Formulářový framework v PHP - InputBox

PHP Knihovny Formulářový framework v PHP - InputBox American English version English version

V minulém dílu našeho seriálu tutoriálů o tvorbě PHP knihoven jsme dokončili předka pro formulářové kontrolky. Nic nám tedy nebrání tomu, abychom si vytvořili první kontrolku.

InputBox

InputBox je kontrolka založená na HTML elementu input. Budeme pomocí ní zadávat text, emaily, URL adresy, čísla a hesla. Kontrolku dále použijeme i pro skrytá pole a tlačítka.

Třída bude opravdu minimalistická a proto si uvedeme rovnou její kompletní kód:

class InputBox extends FormControl
{
        private $text;
        public $type;

        public function __construct($name, $type, $label = '', $htmlParams = array())
        {
                $this->type = $type;
        parent::__construct($name, $label, $htmlParams);
        }

        public function setText($text)
        {
                $this->text = $text;
                return $this;
        }

        public function setData($key, $text)
        {
                $this->text = $text;
        }

        public function renderControl($isPostBack)
        {
                $value = ($isPostBack && isset($_POST[$this->name]) && $this->type != 'password') ? $_POST[$this->name] : $this->text;
                $this->htmlParams['value'] = $value;
                $this->htmlParams['type'] = $this->type;
                $builder = new HtmlBuilder();
                $builder->addElement('input', $this->htmlParams);
                return $builder->render();
        }

}

Třídu jsme podědili z FormControl, což pro nás znamená hlavně že obsahuje validační mechanismy a musí implementovat metodu renderControl().

Atributy tu máme jen dva, jedná se o název a typ inputu, jako je to v HTML.

Konstruktor by měl být jasný, uložíme si typ a zbytek necháme na konstruktoru předka. Na setterech také není nic převratného.

Jediná zajímavá metoda je renderComponent(). Její parametr $isPostBack označuje, zda byl formulář již odeslán (tedy zda jsou v POSTu nějaká data).

Do proměnné $value si uložíme hodnotu, která má být v inputu zobrazená. Bude to buď hodnota, kterou uživatel odeslal nebo výchozí hodnota v poli. Odeslanou hodnotu zobrazíme v případě, že byl formulář již odeslán a my ho zobrazujeme, to může mít totiž jediný důvod - uživatel něco vyplnil špatně a my jsme mu formulář vrátili. Proto input budeme chtít vyplnit znovu hodnotou z POSTu. V případě, že je input typu password nic vyplňovat nebudeme, heslo by měl z bezpečnostních důvodů zadat vždy znovu. Pokud uživatel formulář vyplnil správně, tak po dokončení požadavku přesměrujeme, čímž se ztratí data z POSTu a první situace nenastane. To si ukážeme až dále v seriálu. V ostatnch případech do inputu vypíšeme výchozí text. Ten je ve výchozím stavu prázdný, ale můžeme zde uvést i nějakou výchozí hodnotu. Dále již jen vyrenderujeme input pomocí HtmlBuilderu a výsledné HTML vrátíme.

Testování

Již několik dílů jsme programovali a nemáme ještě žádný měřitelný výstup. Vytvoření třídy formuláře zabere ještě několik dílů a programovat takovou dobu bez výsledku je poněkud demotivující. Proto si udělejme malou pauzu a otestujme náš InputBox, zatím bez formuláře.

Vytvořme si několik formulářových polí. Jejich zápis bude o něco složitější než s formulářovou třídou, ale s tím teď nic neuděláme.

$jmenoBox = new InputBox('jmeno', 'text');
$jmenoBox->addRequiredRule()
        ->addMinLengthRule(3);
$emailBox = new InputBox('email', 'email');
$emailBox->addRequiredRule()
        ->addPatternRule(FormControl::PATTERN_EMAIL)
        ->setText('@');
$hesloBox = new InputBox('heslo', 'password');
$hesloBox->addPasswordRule();
$rodneCisloBox = new InputBox('rodne_cislo', 'text');
$rodneCisloBox->addPatternRule('[0-9]{6}\/[0-9]{4}');
$tlacitko = new InputBox('odeslat', 'submit');
$tlacitko->setText('Odeslat');

$validateClient = true;
$postBack = false;

Kód si vložte třeba do nějakého kontroleru nebo klidně jen do PHP souboru úplně bez architektury. Formulář obsahuje 4 pole a odesílací tlačítko.

Jméno je input typu text, je povinné a musí mít nejméně 3 znaky.

Email je input typu email, jako výchozí obsahuje text "@". Dále se na něj aplikuje pravidlo pro validaci emailu regulárním výrazem, na klientovi není nutné, jelikož email prohlížeč validuje sám, v tomto případě ho tam však již necháme.

Heslo je input typu password a obsahuje pravidlo pro validaci hesla (délka vetší než 5 znaků).

Rodné číslo je input typu text s regulárním výrazem na formát XXXXXX/XXXX.

Proměnná $validateClient určuje, že se mají generovat klientské validace. $postBack obsahuje informaci o tom, zda byl formulář již odeslán. Proměnné jsou samozřejmě vlastností formuláře, ale protože ten ještě nemáme, musíme si je vytvořit takto bokem.

Nyní kontrolky vyrenderujeme, zatím ručně:

<form method="POST">
        Jméno
        <br />
        <?= $jmenoBox->render($validateClient, $postBack) ?>
        <br />
        Email
        <br />
        <?= $emailBox->render($validateClient, $postBack) ?>
        <br />
        Heslo
        <br />
        <?= $hesloBox->render($validateClient, $postBack) ?>
        <br />
        Rodné číslo
        <br />
        <?= $rodneCisloBox->render($validateClient, $postBack) ?>
        <br />
        <?= $tlacitko->render($validateClient, $postBack) ?>
</form>

První parametr metody render určuje zda chceme generovat klientské validace, druhé je zda byl odeslán formulář (situace PostBack).

Výsledek vypadá takto:

InputBox ve formulářovém frameworku PHP

A jeho HTML kód:

<form method="POST">
        Jméno
        <br />
        <input name="jmeno" id="jmeno" required="required" pattern=".{3,}" value="" type="text" />
        <br />
        Email
        <br />
        <input name="email" id="email" required="required" pattern="[a-z0-9._-]+@[a-z0-9.-]+\.[a-z]{2,4}$" value="@" type="email" />
        <br />
        Heslo
        <br />
        <input name="heslo" id="heslo" pattern=".{6,}" value="" type="password" />
        <br />
        Rodné číslo
        <br />
        <input name="rodne_cislo" id="rodne_cislo" pattern="[0-9]{6}\/[0-9]{4}" value="" type="text" />
        <br />
        <input name="odeslat" id="odeslat" value="Odeslat" type="submit" />
</form>

Můžete si zkusit, že klientské validace opravdu fungují. Zadejte si kratší jméno, nevalidní email nebo krátké heslo. Naopak nevyplněné heslo je v pořádku, protože pole není povinné. Rodné číslo musí být rovněž ve správném tvaru a není povinné.

Validace formulářů v PHP

Nakonec otestujeme i validace serverové strany. Proměnnou $validateClient nastavte na false. Další možností by bylo pomocí vývojářské konzole přímo v prohlížeči z HTML kódu jednoduše odmazat atributy pattern a required.

Do PHP doplníme zavolání validací po odeslání formuláře, zatím to musíme udělat napůl ručně:

if ($_POST)
{
        $postBack = true;
        try
        {
                $jmenoBox->checkValidity();
                $emailBox->checkValidity();
                $hesloBox->checkValidity();
                $rodneCisloBox->checkValidity();
        }
        catch (UserException $e)
        {
                echo($e->getMessage());
        }
}

Můžete si opět zkusit udělat různé chyby, všechny budou na serveru zachyceny a vyvolají UserException. Uvidíte také, že hodnoty zůstávají vyplněné i po odeslání formuláře. Obarvení políčka červeně bude mít na svědomí až formulář.

Validace formulářů v PHP

Vidíme, že jsme na správné cestě. Funkční projekt je níže ke stažení. Příště budeme programovat třídu formuláře.


 

Stáhnout

Staženo 271x (8.12 kB)
Aplikace je včetně zdrojových kódů v jazyce php

 

  Aktivity (1)

Článek pro vás napsal David Čápka
Avatar
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.

Jak se ti líbí článek?
Celkem (6 hlasů) :
55555


 


Miniatura
Všechny články v sekci
Knihovny pro PHP

 

 

Komentáře

Avatar
Petr Nymsa
Redaktor
Avatar
Petr Nymsa:

Nevím jestli to někde v článku je, každopádně

public function setData($key, $text)
       {
               $this->text = $text;
       }

proč tam předáváš ještě $key ?

Odpovědět 5.3.2014 17:33
Pokrok nezastavíš, neusni a jdi s ním vpřed
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Petr Nymsa
David Čápka:

Bylo to řečeno když se vyráběl předek, někdy minule nebo předminule. Klíč se používá u kontrolek, které v sobě mají několik hodnot, má to tak třeba třeba CheckList. InputBox má vždy jen jeden text, takže se tam nevyužije, ale kvůli rozhraní tam být musí.

Odpovědět  +1 5.3.2014 17:36
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Petr Nymsa
Redaktor
Avatar
Odpovídá na David Čápka
Petr Nymsa:

Aha, já si myslel že to bude moje chyba a neznalost :`

Odpovědět 5.3.2014 17:56
Pokrok nezastavíš, neusni a jdi s ním vpřed
Avatar
lukigod
Člen
Avatar
lukigod:

Díky za pěkný seriál.
Chci se zeptat proč nevrací setter setData instanci na které byl volán.

 
Odpovědět 5.3.2014 23:46
Avatar
Silvinios
Redaktor
Avatar
Silvinios:

Nebylo by lepší použít pro popisy formulářových položek element LABEL?

 
Odpovědět 6.3.2014 7:35
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na lukigod
David Čápka:

setData() na jednotlivých kontrolkách nebude volat uživatel, ale formulář, asi to tam ještě dopíšu.

Odpovědět 6.3.2014 8:50
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Silvinios
David Čápka:

Label samozřejmě použit bude, jak je v článku řečeno, toto bylo pouze jednoduché otestování, kontrolky bude generovat formulář.

Odpovědět 6.3.2014 8:51
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 7 zpráv z 7.