Formulářové prvky

Přehled standardních formulářových prvků.

addText(string|int $name, $label=null): TextInput

Přidá jednořádkové textové políčko (třída TextInput). Pokud uživatel pole nevyplní, vrací prázdný řetězec '', nebo pomocí setNullable() lze určit, aby vracel null.

$form->addText('name', 'Jméno:')
	->setRequired()
	->setNullable();

Automaticky validuje UTF-8, ořezává levo- a pravostranné mezery a odstraňuje odřádkování, které by mohl odeslat útočník.

Maximální délku lze omezit pomocí setMaxLength(). Pozměnit uživatelem vloženou hodnotu umožňuje addFilter().

Pomocí setHtmlType() lze změnit charakter vstupního prvku na search, tel, url, range, date, datetime-local, month, time, week, color. Místo typů number a email doporučujeme použít addInteger a addEmail, které disponují validací na straně serveru.

$form->addText('color', 'Vyberte barvu:')
	->setHtmlType('color')
	->addRule($form::PATTERN, 'invalid value', '[0-9a-f]{6}');

Prvku lze nastavit tzv. empty-value, což je něco jako výchozí hodnota, ale pokud ji uživatel nezmění, vrátí prvek prázdný řetězec či null.

$form->addText('phone', 'Telefon:')
	->setHtmlType('tel')
	->setEmptyValue('+420');

addTextArea(string|int $name, $label=null): TextArea

Přidá pole pro zadání víceřádkového textu (třída TextArea). Pokud uživatel pole nevyplní, vrací prázdný řetězec '', nebo pomocí setNullable() lze určit, aby vracel null.

$form->addTextArea('note', 'Poznámka:')
	->addRule($form::MAX_LENGTH, 'Poznámka je příliš dlouhá', 10000);

Automaticky validuje UTF-8 a normalizuje oddělovače řádků na \n. Na rozdíl od jednořádkového vstupního políčka k žádnému ořezávání mezer nedochází.

Maximální délku lze omezit pomocí setMaxLength(). Pozměnit uživatelem vloženou hodnotu umožňuje addFilter(). Lze nastavit tzv. empty-value pomocí setEmptyValue().

addInteger(string|int $name, $label=null): TextInput

Přidá políčko pro zadání celočíselného čísla (třída TextInput). Vrací buď integer, nebo null, pokud uživatel nic nezadá.

$form->addInteger('level', 'Úroveň:')
	->setDefaultValue(0)
	->addRule($form::RANGE, 'Úroveň musí být v rozsahu mezi %d a %d.', [0, 100]);

addEmail(string|int $name, $label=null): TextInput

Přidá políčko pro zadání e-mailové adresy (třída TextInput). Pokud uživatel pole nevyplní, vrací prázdný řetězec '', nebo pomocí setNullable() lze určit, aby vracel null.

$form->addEmail('email', 'E-mail:');

Ověří, zda je hodnota platná e-mailová adresa. Neověřuje se, zda doména skutečně existuje, ověřuje se pouze syntaxe. Automaticky validuje UTF-8, ořezává levo- a pravostranné mezery.

Maximální délku lze omezit pomocí setMaxLength(). Pozměnit uživatelem vloženou hodnotu umožňuje addFilter(). Lze nastavit tzv. empty-value pomocí setEmptyValue().

addPassword(string|int $name, $label=null): TextInput

Přidá políčko pro zadání hesla (třída TextInput).

$form->addPassword('password', 'Heslo:')
	->setRequired()
	->addRule($form::MIN_LENGTH, 'Heslo musí mít alespoň %d znaků', 8)
	->addRule($form::PATTERN, 'Musí obsahovat číslici', '.*[0-9].*');

Při znovuzobrazení formuláře bude políčko prázdné. Automaticky validuje UTF-8, ořezává levo- a pravostranné mezery a odstraňuje odřádkování, které by mohl odeslat útočník.

addCheckbox(string|int $name, $caption=null): Checkbox

Přidá zaškrtávací políčko (třída Checkbox). Vrací hodnotu buď true nebo false, podle toho, zda je zaškrtnuté.

$form->addCheckbox('agree', 'Souhlasím s podmínkami')
	->setRequired('Je potřeba souhlasit s podmínkami');

addCheckboxList(string|int $name, $label=null, array $items=null): CheckboxList

Přidá zaškrtávací políčka pro výběr více položek (třída CheckboxList). Vrací pole klíčů vybraných položek. Metoda getSelectedItems() vrací hodnoty místo klíčů.

$form->addCheckboxList('colors', 'Barvy:', [
	'r' => 'červená',
	'g' => 'zelená',
	'b' => 'modrá',
]);

Pole nabízených položek předáme jako třetí parametr nebo metodou setItems().

Pomocí setDisabled(['r', 'g']) lze deaktivovat jednotlivé položky.

Prvek automaticky kontroluje, že nedošlo k podvržení a že vybrané položky jsou skutečně jedněmi z nabízených a nebyly deaktivovaná. Metodou getRawValue() lze získat odeslané položky bez této důležité kontroly.

Při nastavení výchozích vybraných položek také kontroluje, že jde o jedny z nabízených, jinak vyhodí výjimku. Tuto kontrolu lze vypnout pomocí checkDefaultValue(false).

addRadioList(string|int $name, $label=null, array $items=null): RadioList

Přidá přepínací tlačítka (třída RadioList). Vrací klíč vybrané položky, nebo null, pokud uživatel nic nevybral. Metoda getSelectedItem() vrací hodnotu místo klíče.

$sex = [
	'm' => 'muž',
	'f' => 'žena',
];
$form->addRadioList('gender', 'Pohlaví:', $sex);

Pole nabízených položek předáme jako třetí parametr nebo metodou setItems().

Pomocí setDisabled(['m', 'f']) lze deaktivovat jednotlivé položky.

Prvek automaticky kontroluje, že nedošlo k podvržení a že vybraná položka je skutečně jednou z nabízených a nebyla deaktivovaná. Metodou getRawValue() lze získat odeslanou položku bez této důležité kontroly.

Při nastavení výchozí vybrané položky také kontroluje, že jde o jednou z nabízených, jinak vyhodí výjimku. Tuto kontrolu lze vypnout pomocí checkDefaultValue(false).

addSelect(string|int $name, $label=null, array $items=null): SelectBox

Přidá select box (třída SelectBox). Vrací klíč vybrané položky, nebo null, pokud uživatel nic nevybral. Metoda getSelectedItem() vrací hodnotu místo klíče.

$countries = [
	'CZ' => 'Česká Republika',
	'SK' => 'Slovensko',
	'GB' => 'Velká Británie',
];

$form->addSelect('country', 'Země:', $countries)
	->setDefaultValue('SK');

Pole nabízených položek předáme jako třetí parametr nebo metodou setItems(). Položky mohou být i dvourozměrné pole:

$countries = [
	'Europe' => [
		'CZ' => 'Česká Republika',
		'SK' => 'Slovensko',
		'GB' => 'Velká Británie',
	],
	'CA' => 'Kanada',
	'US' => 'USA',
	'?'  => 'jiná',
];

U select boxů má často první položka speciální význam, slouží jako výzva k akci. K přidání takové položky slouží metoda setPrompt().

$form->addSelect('country', 'Země:', $countries)
	->setPrompt('Zvolte zemi');

Pomocí setDisabled(['CZ', 'SK']) lze deaktivovat jednotlivé položky.

Prvek automaticky kontroluje, že nedošlo k podvržení a že vybraná položka je skutečně jednou z nabízených a nebyla deaktivovaná. Metodou getRawValue() lze získat odeslanou položku bez této důležité kontroly.

Při nastavení výchozí vybrané položky také kontroluje, že jde o jednou z nabízených, jinak vyhodí výjimku. Tuto kontrolu lze vypnout pomocí checkDefaultValue(false).

addMultiSelect(string|int $name, $label=null, array $items=null): MultiSelectBox

Přidá select box pro výběr více položek (třída MultiSelectBox). Vrací pole klíčů vybraných položek. Metoda getSelectedItems() vrací hodnoty místo klíčů.

$form->addMultiSelect('countries', 'Země:', $countries);

Pole nabízených položek předáme jako třetí parametr nebo metodou setItems(). Položky mohou být i dvourozměrné pole.

Pomocí setDisabled(['CZ', 'SK']) lze deaktivovat jednotlivé položky.

Prvek automaticky kontroluje, že nedošlo k podvržení a že vybrané položky jsou skutečně jedněmi z nabízených a nebyly deaktivovaná. Metodou getRawValue() lze získat odeslané položky bez této důležité kontroly.

Při nastavení výchozích vybraných položek také kontroluje, že jde o jedny z nabízených, jinak vyhodí výjimku. Tuto kontrolu lze vypnout pomocí checkDefaultValue(false).

addUpload(string|int $name, $label=null): UploadControl

Přidá políčko pro upload souboru (třída UploadControl). Vrací objekt FileUpload a to i v případě, že uživatel žádný soubor neodeslal, což lze zjistit metodou FileUpload::hasFile().

$form->addUpload('avatar', 'Avatar:')
	->setRequired(false) // nepovinný
	->addRule($form::IMAGE, 'Avatar musí být JPEG, PNG or GIF.')
	->addRule($form::MAX_FILE_SIZE, 'Maximální velikost je 1 MB.', 1024 * 1024);

Pokud se soubor nepodaří korektně nahrát, formulář není úspěšně odeslaný a zobrazí se chyba. Tj. při úspěšném odeslání není potřeba ověřovat metodu FileUpload::isOk().

Nikdy nevěřte originálnímu názvu souboru vráceného metodou FileUpload::getName(), klient mohl odeslat škodlivý název souboru s úmyslem poškodit nebo hacknout vaši aplikaci.

Pravidla MIME_TYPE a IMAGE detekují požadovaný typ na základě signatury souboru a neověřují jeho integritu. Zda není obrázek poškozený lze zjistit například pokusem o jeho načtení.

addMultiUpload(string|int $name, $label=null): UploadControl

Přidá políčko pro upload více souboru najednou (třída UploadControl). Vrací pole objektů FileUpload. Metoda FileUpload::hasFile() u každého z nich bude vracet true.

$form->addMultiUpload('files', 'Soubory:')
	->addRule($form::MAX_LENGTH, 'Maximálně lze nahrát %d souborů', 10);

Pokud se některý soubor nepodaří korektně nahrát, formulář není úspěšně odeslaný a zobrazí se chyba. Tj. při úspěšném odeslání není potřeba ověřovat metodu FileUpload::isOk().

Nikdy nevěřte originálním názvům souborů vráceným metodou FileUpload::getName(), klient mohl odeslat škodlivý název souboru s úmyslem poškodit nebo hacknout vaši aplikaci.

Pravidla MIME_TYPE a IMAGE detekují požadovaný typ na základě signatury souboru a neověřují jeho integritu. Zda není obrázek poškozený lze zjistit například pokusem o jeho načtení.

addHidden(string|int $name, string $default=null): HiddenField

Přidá skryté pole (třída HiddenField).

$form->addHidden('userid');

Pomocí setNullable() lze nastavit, aby vracel null místo prázdného řetězce. Pozměnit odeslanou hodnotu umožňuje addFilter().

addSubmit(string|int $name, $caption=null): SubmitButton

Přidá odesílací tlačítko (třída SubmitButton).

$form->addSubmit('submit', 'Odeslat');

Ve formuláři je možné mít i více odesílacích tlačítek:

$form->addSubmit('register', 'Register');
$form->addSubmit('cancel', 'Cancel');

Ke zjištění, na které z nich bylo kliknuto, použijte:

if ($form['register']->isSubmittedBy()) {
  // ...
}

Pokud nechcete validovat celý formulář při stisknutí tlačítka (například u tlačítek Zrušit nebo Náhled), použijte setValidationScope().

addButton(string|int $name, $caption)Button

Přidá tlačítko (třída Button), které nemá odesílací funkci. Lze ho tedy využít na nějakou jinou funkci, např. zavolání JavaScriptové funkce při kliknutí.

$form->addButton('raise', 'Zvýšit plat')
	->setHtmlAttribute('onclick', 'raiseSalary()');

addImage(string|int $name, string $src=null, string $alt=null): ImageButton

Přidá odesílací tlačítko v podobě obrázku (třída ImageButton).

$form->addImage('submit', '/path/to/image');

Při použití více odeslacích tlačítek lze zjistit, na které bylo kliknuto, pomocí $form['submit']->isSubmittedBy().

addContainer(string|int $name): Container

Přidá podformulář (třída Container), nebo-li kontejner, do kterého lze přidávat další prvky stejným způsobem, jako je přidáváme do formuláře. Fungují i metody setDefaults() nebo getValues().

$sub1 = $form->addContainer('first');
$sub1->addText('name', 'Your name:');
$sub1->addEmail('email', 'Email:');

$sub2 = $form->addContainer('second');
$sub2->addText('name', 'Your name:');
$sub2->addEmail('email', 'Email:');

Odeslaná data pak vrací jako vícerozměrnou strukturu:

[
	'first' => [
		'name' => ...,
		'email' => ...,
	],
	'second' => [
		'name' => ...,
		'email' => ...,
	],
]

Další nastavení

Všem formulářovým prvkům lze nastavit výchozí hodnotu pomocí setDefaultValue() a získat aktuální hodnotu pomocí getValue().

Popisku lze měnit pomocí setCaption(string|object $caption).

Můžete měnit přímo jednotlivé atributy HTML elementu pomocí setHtmlAttribute(). Pro atributy id a name jsou k dispozici navíc metody setHtmlId($id), getHtmlId() a getHtmlName().

Jednotlivým formulářovým prvkům je možné nastavit překladač pomocí setTranslator().

Prvkům lze přiřadit také uživatelské data pomocí setOption($key, $value) a číst je pomocí getOption($key). Můžete tak například prvkům předat informace, které využijete při vykreslování.

Dále lze nastavovat validační pravidla pomocí metod addRule(), addCondition() a dalších.

Vynechané hodnoty

Pokud nás uživatelem vyplněná hodnota nezajímá, můžeme ji pomocí setOmitted() vynechat z výsledku metody $form->getValues() nebo z dat předávaných do handlerů. To se hodí pro různá hesla pro kontrolu, antispamové prvky atd.

$form->addPassword('passwordVerify', 'Heslo pro kontrolu:')
	->setRequired('Zadejte prosím heslo ještě jednou pro kontrolu')
	->addRule($form::EQUAL, 'Hesla se neshodují', $form['password'])
	->setOmitted();

Deaktivace prvků

Prvky lze deaktivovat pomocí setDisabled(). Takový prvek nemůže uživatel editovat.

$form->addText('username', 'Uživatelské jméno:')
	->setDisabled();

Upozorňujeme, že disablované prvky prohlížeč vůbec neodesílá na server, tedy je ani nenajdete v datech vrácených funkcí $form->getValues().

Pokud prvku nastavujete výchozí hodnotu, je tak nutné učinit až po jeho deaktivaci:

$form->addText('username', 'Uživatelské jméno:')
	->setDisabled()
	->setDefaultValue($userName);

Vlastní prvky

Vedle široké škály vestavěných formulářových prvků můžete do formuláře přidávat vlastní prvky tímto způsobem:

$form->addComponent(new DateInput('Datum:'), 'date');
// alternativní syntax: $form['date'] = new DateInput('Datum:');

Existuje způsob, jak definovat nové metody formuláře sloužící k přidávání vlastních prvků (např. $form->addZip()). Jde o tzv. extension methods. Nevýhoda je, že pro ně nebude fungovat napovídání v editorech.

use Nette\Forms\Container;

// přidáme metodu addZip(string $name, string $label = null)
Container::extensionMethod('addZip', function (Container $form, $name, $label = null) {
	return $form->addText($name, $label)
		->setRequired(false)
		->addRule($form::PATTERN, 'Alespoň 5 čísel', '[0-9]{5}');
});

// použití
$form->addZip('zip', 'ZIP code:');

Low-level prvky

Lze používat i prvky, které zapíšeme pouze v šabloně a nepřidáme je do formuláře některou z metod $form->addXyz(). Když například vypisujeme záznamy z databáze a dopředu nevíme, kolik jich bude a jaké budou mít ID, a chceme u každého řádku zobrazit checkbox nebo radio button, stačí jej nakódovat v šabloně:

{foreach $items as $item}
	<p><input type=checkbox name="sel[]" value={$item->id}> {$item->name}</p>
{/foreach}

A po odeslání hodnotu zjistíme:

$values = $form->getHttpData($form::DATA_TEXT, 'sel[]');
$values = $form->getHttpData($form::DATA_TEXT | $form::DATA_KEYS, 'sel[]');

kde první parametr je typ elementu (DATA_FILE pro type=file, DATA_LINE pro jednořádkové vstupy jako text, password, email apod. a DATA_TEXT pro všechny ostatní) a druhý parametr sel[] odpovídá HTML atributu name. Typ elementu můžeme kombinovat s hodnotou DATA_KEYS, která zachová klíče prvků. To se hodí zejména pro select, radioList a checkboxList.

Podstatné je, že getHttpData() vrací sanitizovanou hodnotu, v tomto případě to bude vždy pole validních UTF-8 řetězců, ať už by se pokusil útočník serveru podstrčit cokoliv. Jde o obdobu přímé práce s $_POST nebo $_GET avšak s tím podstatným rozdílem, že vždy vrací čistá data, tak, jak jste zvyklí u standardních prvků Nette formulářů.


Související články na blogu

Vylepšit tuto stránku