IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 5 - Formulářový framework v PHP - InputBox

V minulé lekci, Dokončení třídy FormControl v PHP, jsme dokončili předka pro formulářové kontrolky - abstraktní třídu FormControl.

Dnes si vytvoříme 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 string $text = '';

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

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

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

    public function renderControl(bool $isPostBack) : string
    {
        $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 třídy 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 superproměnné POST 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. V případě, že je input typu password, nic vyplňovat nebudeme, heslo by měl z bezpečnostních důvodů uživatel zadat vždy znovu. Pokud uživatel formulář vyplnil správně, tak ho po dokončení požadavku přesměrujeme. V ostatních 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 defaultní 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 čtyři pole a odesílací tlačítko.

Jméno je input typu text, je povinné a musí mít nejméně tři 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. Proměnná $postBack obsahuje informaci o tom, zda byl formulář již odeslán. Proměnné jsou samozřejmě vlastnosti 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ý uvádí, zda byl odeslán formulář.

Výsledek vypadá takto:

InputBox ve formulářovém frameworku PHP - Pokročilá obsluha formulářů v 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 - Pokročilá obsluha formulářů v PHP

Nakonec otestujeme i validace serverové strany. Proměnnou $validateClient nastavme na hodnotu 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í výjimku 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 - Pokročilá obsluha formulářů v PHP

Vidíme, že jsme na správné cestě. Funkční projekt je níže ke stažení.

Příště, v lekci Formulářový framework v PHP - Formulář, budeme programovat třídu formuláře.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 479x (8.08 kB)
Aplikace je včetně zdrojových kódů v jazyce PHP

 

Předchozí článek
Dokončení třídy FormControl v PHP
Všechny články v sekci
Pokročilá obsluha formulářů v PHP
Přeskočit článek
(nedoporučujeme)
Formulářový framework v PHP - Formulář
Článek pro vás napsal David Hartinger
Avatar
Uživatelské hodnocení:
16 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity