Formulářové prvky

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

addText (string|int $name, $label=null, $cols, ?int $maxLength=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 vizuální charakter textového pole na typy jako search, tel nebo url viz specifikace. Pamatujte, že změna typu je pouze vizuální a nezastupuje funkci validace. Pro typ url je vhodné přidat specifické validační pravidlo URL.

Pro další typy vstupů, jako number, range, email, date, datetime-local, time a color, použijte specializované metody jako addInteger, addFloat, addEmail addDate, addTime, addDateTime a addColor, které zajišťují serverovou validaci. Typy month a week zatím nejsou plně podporovány ve všech prohlížečích.

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::MaxLength, '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('year', 'Rok:')
	->addRule($form::Range, 'Rok musí být v rozsahu od %d do %d.', [1900, 2023]);

Prvek se vykresluje jako <input type="numeric">. Použitím metody setHtmlType() lze změnit typ na range pro zobrazení v podobě posuvníku, nebo na text, pokud preferujete standardní textové pole bez speciálního chování typu numeric.

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

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

$form->addFloat('level', 'Úroveň:')
	->setDefaultValue(0)
	->addRule($form::Range, 'Úroveň musí být v rozsahu od %d do %d.', [0, 100]);

Prvek se vykresluje jako <input type="numeric">. Použitím metody setHtmlType() lze změnit typ na range pro zobrazení v podobě posuvníku, nebo na text, pokud preferujete standardní textové pole bez speciálního chování typu numeric.

Nette a prohlížeč Chrome akceptují jako oddělovač desetinných míst jak čárku, tak tečku. Aby byla tato funkcionalita dostupná i ve Firefoxu, je doporučeno nastavit atribut lang buď pro daný prvek nebo pro celou stránku, například <html lang="cs">.

addEmail (string|int $name, $label=null, int $maxLength=255): 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, $cols, ?int $maxLength=null): TextInput

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

$form->addPassword('password', 'Heslo:')
	->setRequired()
	->addRule($form::MinLength, '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).

Pokud odesíláte formulář metodou GET, můžete zvolit kompaktnější způsob přenosu dat, který šetří velikost query stringu. Aktivuje se nastavením HTML atributu formuláře:

$form->setHtmlAttribute('data-nette-compact');

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, ?int $size=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, ?int $size=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:')
	->addRule($form::Image, 'Avatar musí být JPEG, PNG, GIF, WebP or AVIF.')
	->addRule($form::MaxFileSize, '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 MimeType 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::MaxLength, '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 MimeType 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í.

addDate (string|int $name, $label=null): DateTimeControl

Přidá políčko, které umožní uživateli snadno zadat datum skládající se z roku, měsíce a dne (třída DateTimeControl).

Jako výchozí hodnotu akceptuje buď objekty implementující rozhraní DateTimeInterface, řetězec s časem, nebo číslo představující UNIX timestamp. Totéž platí pro argumenty pravidel Min, Max nebo Range, jež definují minimální a maximální povolený datum.

$form->addDate('date', 'Datum:')
	->setDefaultValue(new DateTime)
	->addRule($form::Min, 'Datum musí být minimálně měsíc staré.', new DateTime('-1 month'));

Standardně vrací objekt DateTimeImmutable, metodou setFormat() můžete specifikovat textový formát či timestamp:

$form->addDate('date', 'Datum:')
	->setFormat('Y-m-d');

addTime (string|int $name, $label=null, bool $withSeconds=false): DateTimeControl

Přidá políčko, které umožní uživateli snadno zadat čas skládající se z hodin, minut a volitelně i sekund (třída DateTimeControl).

Jako výchozí hodnotu akceptuje buď objekty implementující rozhraní DateTimeInterface, řetězec s časem, nebo číslo představující UNIX timestamp. Z těchto vstupů je využita pouze časová informace, datum je ignorováno. Totéž platí pro argumenty pravidel Min, Max nebo Range, jež definují minimální a maximální povolený čas. Pokud je nastavená minimální hodnota vyšší než maximální, vytvoří se časový rozsah přesahující půlnoc.

$form->addTime('time', 'Čas:', withSeconds: true)
	->addRule($form::Range, 'Čas musí být v rozsahu od %d do %d.', ['12:30', '13:30']);

Standardně vrací objekt DateTimeImmutable (s datem 1. ledna roku 1), metodou setFormat() můžete specifikovat textový formát:

$form->addTime('time', 'Čas:')
	->setFormat('H:i');

addDateTime (string|int $name, $label=null, bool $withSeconds=false): DateTimeControl

Přidá políčko, které umožní uživateli snadno zadat datum a čas skládající se z roku, měsíce, dne, hodin, minut a volitelně i sekund (třída DateTimeControl).

Jako výchozí hodnotu akceptuje buď objekty implementující rozhraní DateTimeInterface, řetězec s časem, nebo číslo představující UNIX timestamp. Totéž platí pro argumenty pravidel Min, Max nebo Range, jež definují minimální a maximální povolený datum.

$form->addDateTime('datetime', 'Datum a čas:')
	->setDefaultValue(new DateTime)
	->addRule($form::Min, 'Datum musí být minimálně měsíc staré.', new DateTime('-1 month'));

Standardně vrací objekt DateTimeImmutable, metodou setFormat() můžete specifikovat textový formát či timestamp:

$form->addDateTime('datetime')
	->setFormat(DateTimeControl::FormatTimestamp);

addColor (string|int $name, $label=null): ColorPicker

Přidá políčko pro výběr barvy (třída ColorPicker). Barva je řetězec ve tvaru #rrggbb. Pokud uživatel volbu neprovede, vrátí se černá barva #000000.

$form->addColor('color', 'Barva:')
	->setDefaultValue('#3C8ED7');

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().

Ačkoli je prvek skrytý, je důležité si uvědomit, že hodnota může být stále modifikována nebo podvržena útočníkem. Vždy důkladně ověřujte a validujte všechny přijaté hodnoty na serverové straně, aby se předešlo bezpečnostním rizikům spojeným s manipulací dat.

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()');

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

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

$form->addImageButton('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' => /* ... */,
	],
]

Přehled nastavení

U všech prvků můžeme volat následující metody (kompletní přehled v API dokumetaci):

setDefaultValue($value) nastaví výchozí hodnotu
getValue() získat aktuální hodnotu
setOmitted() vynechání hodnoty
setDisabled() deaktivace prvků

Vykreslování:

setCaption($caption) změní popisku prvku
setTranslator($translator) nastaví překladač
setHtmlAttribute($name, $value) nastaví HTML atribut elementu
setHtmlId($id) nastaví HTML atribut id
setHtmlType($type) nastaví HTML atribut type
setHtmlName($name) nastaví HTML atribut name
setOption($key, $value) nastavení pro vykreslování

Validace:

setRequired() povinný prvek
addRule() nastavení validační pravidlo
addCondition(), addConditionOn() nastaví validační podmínku
addError($message) předání chybové zprávy

U prvků addText(), addPassword(), addTextArea(), addEmail(), addInteger() lze volat následující metody:

setNullable() nastaví, zda getValue() vrátí null místo prázdného řetězce
setEmptyValue($value) nastaví speciální hodnotu, která se považuje za prázdný řetězec
setMaxLength($length) nastaví maximální počet povolených znaků
addFilter($filter) úprava vstupu

Vynechání 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();

Disablované prvky prohlížeč vůbec neodesílá na server, tedy je ani nenajdete v datech vrácených funkcí $form->getValues(). Pokud však nastavíte setOmitted(false), Nette do těchto dat zahrne jejich výchozí hodnotu.

Při volání setDisabled() se z bezpečnostních důvodů smaže hodnota prvku. Pokud nastavujete výchozí hodnotu, je tak nutné učinit až po jeho deaktivaci:

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

Alternativou disablovaných prvků jsou prvky s HTML atributem readonly, které prohlížeč na server posílá. Ačkoliv je prvek pouze pro čtení, je důležité si uvědomit, že jeho hodnota může být stále modifikována nebo podvržena útočníkem.

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

Formulář je potomkem třídy Container a jednotlivé prvky jsou potomky Component.

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, string $name, ?string $label = null) {
	return $form->addText($name, $label)
		->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:

$data = $form->getHttpData($form::DataText, 'sel[]');
$data = $form->getHttpData($form::DataText | $form::DataKeys, 'sel[]');

kde první parametr je typ elementu (DataFile pro type=file, DataLine pro jednořádkové vstupy jako text, password, email apod. a DataText pro všechny ostatní) a druhý parametr sel[] odpovídá HTML atributu name. Typ elementu můžeme kombinovat s hodnotou DataKeys, 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ářů.

verze: 4.0 3.x 2.x