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ářů.