Form Controls
Overview of built-in form controls.
addText(string|int $name, $label=null, $cols, ?int $maxLength=null): TextInput
Adds single line text field (class TextInput). If the user does not fill in the field,
it returns an empty string ''
, or use setNullable()
to change it to return null
.
$form->addText('name', 'Name:')
->setRequired()
->setNullable();
It automatically validates UTF-8, trims left and right whitespaces, and removes line breaks that could be sent by an attacker.
The maximum length can be limited using setMaxLength()
. The addFilter() allows you to change the user-entered value.
You can change the visual character of a text field to types like search
, tel
, or url
using setHtmlType()
, as seen in the specification. Remember that changing the type
is only visual and does not perform validation functions. For the url
type, it is appropriate to add a specific URL rule.
For other input types such as number
, range
, email
, date
,
datetime-local
, time
, and color
, use specialized methods like addInteger, addFloat, addEmail addDate, addTime, addDateTime, and addColor, which ensure server-side validation. The types month
and week
are not
yet fully supported in all browsers.
The so-called empty-value can be set for the element, which is something like the default value, but if the user does not
overwrite it, returns empty string or null
.
$form->addText('phone', 'Phone:')
->setHtmlType('tel')
->setEmptyValue('+420');
addTextArea(string|int $name, $label=null): TextArea
Adds a multiline text field (class TextArea).
If the user does not fill in the field, it returns an empty string ''
, or use setNullable()
to change it
to return null
.
$form->addTextArea('note', 'Note:')
->addRule($form::MAX_LENGTH, 'Your note is way too long', 10000);
Automatically validates UTF-8 and normalizes line breaks to \n
. Unlike a single-line input field, it does not
trim the whitespace.
The maximum length can be limited using setMaxLength()
. The addFilter() allows you to change the user-entered value. You can set the
so-called empty-value using setEmptyValue()
.
addInteger(string|int $name, $label=null): TextInput
Adds input field for integer (class TextInput). Returns either an integer or
null
if the user does not enter anything.
$form->addInteger('year', 'Year:')
->addRule($form::RANGE, 'The year must be in the range %d to %d.', [1900, 2023]);
The element is rendered as <input type="numeric">
. By using the setHtmlType()
method, you can
change the type to range
for display as a slider, or to text
if you prefer a standard text field without
the special behavior of numeric
.
addFloat(string|int $name, $label=null): TextInput
Adds a field for entering a decimal number (TextInput class). Returns either float or
null
, if the user does not specify anything.
$form->addFloat('level', 'Level:')
->setDefaultValue(0)
->addRule($form::RANGE, 'The level must be in the range %d to %d.', [0, 100]);
The element is rendered as <input type="numeric">
. By using the setHtmlType()
method, you can
change the type to range
for display as a slider, or to text
if you prefer a standard text field without
the special behavior of numeric
.
Nette and the Chrome browser accept both a comma and a dot as decimal separators. To make this functionality available in
Firefox, it is recommended to set the lang
attribute either for the specific element or for the entire page, for
example, <html lang="cs">
.
addEmail(string|int $name, $label=null, int $maxLength=255): TextInput
Adds email address field with validity check (class TextInput). If the user does not fill in the field,
it returns an empty string ''
, or use setNullable()
to change it to return null
.
$form->addEmail('email', 'Email:');
Verifies that the value is a valid email address. It does not verify that the domain actually exists, only the syntax is verified. Automatically validates UTF-8, trims left and right whitespaces.
The maximum length can be limited using setMaxLength()
. The addFilter() allows you to change the user-entered value. You can set the
so-called empty-value using setEmptyValue()
.
addPassword(string|int $name, $label=null, $cols, ?int $maxLength=null): TextInput
Adds password field (class TextInput).
$form->addPassword('password', 'Password:')
->setRequired()
->addRule($form::MIN_LENGTH, 'Password has to be at least %d characters long', 8)
->addRule($form::PATTERN, 'Password must contain a number', '.*[0-9].*');
When you re-send the form, the input will be blank. It automatically validates UTF-8, trims left and right whitespaces, and removes line breaks that could be sent by an attacker.
addCheckbox(string|int $name, $caption=null): Checkbox
Adds a checkbox (class Checkbox). The field
returns either true
or false
, depending on whether it is checked.
$form->addCheckbox('agree', 'I agree with terms')
->setRequired('You must agree with our terms');
addCheckboxList(string|int $name, $label=null, ?array $items=null): CheckboxList
Adds list of checkboxes for selecting multiple items (class CheckboxList). Returns the array of keys of the
selected items. The getSelectedItems()
method returns values instead of keys.
$form->addCheckboxList('colors', 'Colors:', [
'r' => 'red',
'g' => 'green',
'b' => 'blue',
]);
We pass the array of items as the third parameter, or by the setItems()
method.
You can use setDisabled(['r', 'g'])
to disable individual items.
The element automatically checks that there has been no forgery and that the selected items are actually one of the offered
ones and have not been disabled. The getRawValue()
method can be used to retrieve submitted items without this
important check.
When default values are set, it also checks that they are one of the offered items, otherwise it throws an exception. This
check can be turned off with checkDefaultValue(false)
.
If you are submitting a form using the GET
method, you can choose a more compact data transfer method that saves
on the size of the query string. This is activated by setting the HTML attribute of the form:
$form->setHtmlAttribute('data-nette-compact');
addRadioList(string|int $name, $label=null, ?array $items=null): RadioList
Adds radio buttons (class RadioList). Returns
the key of the selected item, or null
if the user did not select anything. The getSelectedItem()
method
returns a value instead of a key.
$sex = [
'm' => 'male',
'f' => 'female',
];
$form->addRadioList('gender', 'Gender:', $sex);
We pass the array of items as the third parameter, or by the setItems()
method.
You can use setDisabled(['m'])
to disable individual items.
The element automatically checks that there has been no forgery and that the selected item is actually one of the offered ones
and has not been disabled. The getRawValue()
method can be used to retrieve the submitted item without this
important check.
When default value is set, it also checks that it is one of the offered items, otherwise it throws an exception. This check can
be turned off with checkDefaultValue(false)
.
addSelect(string|int $name, $label=null, ?array $items=null, ?int $size=null): SelectBox
Adds select box (class SelectBox). Returns
the key of the selected item, or null
if the user did not select anything. The getSelectedItem()
method
returns a value instead of a key.
$countries = [
'CZ' => 'Czech republic',
'SK' => 'Slovakia',
'GB' => 'United Kingdom',
];
$form->addSelect('country', 'Country:', $countries)
->setDefaultValue('SK');
We pass the array of items as the third parameter, or by the setItems()
method. The array of items can also be
two-dimensional:
$countries = [
'Europe' => [
'CZ' => 'Czech republic',
'SK' => 'Slovakia',
'GB' => 'United Kingdom',
],
'CA' => 'Canada',
'US' => 'USA',
'?' => 'other',
];
For select boxes, the first item often has a special meaning, it serves as a call-to-action. Use the setPrompt()
method to add such an entry.
$form->addSelect('country', 'Country:', $countries)
->setPrompt('Pick a country');
You can use setDisabled(['CZ', 'SK'])
to disable individual items.
The element automatically checks that there has been no forgery and that the selected item is actually one of the offered ones
and has not been disabled. The getRawValue()
method can be used to retrieve the submitted item without this
important check.
When default value is set, it also checks that it is one of the offered items, otherwise it throws an exception. This check can
be turned off with checkDefaultValue(false)
.
addMultiSelect(string|int $name, $label=null, ?array $items=null, ?int $size=null): MultiSelectBox
Adds multichoice select box (class MultiSelectBox). Returns the array of keys of
the selected items. The getSelectedItems()
method returns values instead of keys.
$form->addMultiSelect('countries', 'Countries:', $countries);
We pass the array of items as the third parameter, or by the setItems()
method. The array of items can also be
two-dimensional.
You can use setDisabled(['CZ', 'SK'])
to disable individual items.
The element automatically checks that there has been no forgery and that the selected items are actually one of the offered
ones and have not been disabled. The getRawValue()
method can be used to retrieve submitted items without this
important check.
When default values are set, it also checks that they are one of the offered items, otherwise it throws an exception. This
check can be turned off with checkDefaultValue(false)
.
addUpload(string|int $name, $label=null): UploadControl
Adds file upload field (class UploadControl). Returns the FileUpload object, even if the user has not uploaded a file, which can be find out by the
FileUpload::hasFile()
method.
$form->addUpload('avatar', 'Avatar:')
->addRule($form::IMAGE, 'Avatar must be JPEG, PNG, GIF or WebP')
->addRule($form::MAX_FILE_SIZE, 'Maximum size is 1 MB', 1024 * 1024);
If the file did not upload correctly, the form was not submitted successfully and an error is displayed. I.e. it is not
necessary to check the FileUpload::isOk()
method.
Do not trust the original file name returned by method FileUpload::getName()
, a client could send a malicious
filename with the intention to corrupt or hack your application.
Rules MIME_TYPE
and IMAGE
detect required type of file or image by its signature. The integrity of
the entire file is not checked. You can find out if an image is not corrupted for example by trying to load it.
addMultiUpload(string|int $name, $label=null): UploadControl
Adds multiple file upload field (class UploadControl). Returns an array of objects FileUpload. The FileUpload::hasFile()
method will return true
for
each of them.
$form->addMultiUpload('files', 'Files:')
->addRule($form::MAX_LENGTH, 'A maximum of %d files can be uploaded', 10);
If one of the files fails to upload correctly, the form was not submitted successfully and an error is displayed. I.e. it is
not necessary to check the FileUpload::isOk()
method.
Do not trust the original file names returned by method FileUpload::getName()
, a client could send a malicious
filename with the intention to corrupt or hack your application.
Rules MIME_TYPE
and IMAGE
detect required type of file or image by its signature. The integrity of
the entire file is not checked. You can find out if an image is not corrupted for example by trying to load it.
addDate(string|int $name, $label=null): DateTimeControl
Adds a field that allows the user to easily input a date consisting of year, month, and day (class DateTimeControl).
For the default value, it accepts either objects implementing the DateTimeInterface
, a string with time, or a
number representing a UNIX timestamp. The same applies to the Min
, Max
, or Range
rule
arguments, which define the minimum and maximum allowed date.
$form->addDate('date', 'Date:')
->setDefaultValue(new DateTime)
->addRule($form::Min, 'The date must be at least a month old.', new DateTime('-1 month'));
By default, it returns a DateTimeImmutable
object. Using the setFormat()
method, you can specify a text format or timestamp:
$form->addDate('date', 'Date:')
->setFormat('Y-m-d');
addTime(string|int $name, $label=null, bool $withSeconds=false): DateTimeControl
Adds a field that allows the user to easily input time consisting of hours, minutes, and optionally seconds (class DateTimeControl).
For the default value, it accepts either objects implementing the DateTimeInterface
, a string with time, or a
number representing a UNIX timestamp. Only the time information from these inputs is used; the date is ignored. The same applies
to the Min
, Max
, or Range
rule arguments, which define the minimum and maximum allowed
time. If the minimum value set is higher than the maximum, a time range spanning midnight is created.
$form->addTime('time', 'Time:', withSeconds: true)
->addRule($form::Range, 'Time must be between %d and %d.', ['12:30', '13:30']);
By default, it returns a DateTimeImmutable
object (with a fictitious date of January 1, year 0). Using the
setFormat()
method, you can specify a text format:
$form->addTime('time', 'Time:')
->setFormat('H:i');
addDateTime(string|int $name, $label=null, bool $withSeconds=false): DateTimeControl
Adds a field that allows the user to easily input both date and time consisting of year, month, day, hours, minutes, and optionally seconds (class DateTimeControl).
For the default value, it accepts either objects implementing the DateTimeInterface
, a string with time, or a
number representing a UNIX timestamp. The same applies to the Min
, Max
, or Range
rule
arguments, which define the minimum and maximum allowed date.
$form->addDateTime('datetime', 'Date and Time:')
->setDefaultValue(new DateTime)
->addRule($form::Min, 'The date must be at least a month old.', new DateTime('-1 month'));
By default, it returns a DateTimeImmutable
object. Using the setFormat()
method, you can specify a text format or timestamp:
$form->addDateTime('datetime')
->setFormat(DateTimeControl::FormatTimestamp);
addColor(string|int $name, $label=null): ColorPicker
Adds a color selection field (class ColorPicker). The color is a string in the format
#rrggbb
. If the user doesn't make a selection, the default color returned is black #000000
.
$form->addColor('color', 'Color:')
->setDefaultValue('#3C8ED7');
addHidden(string|int $name, ?string $default=null): HiddenField
Adds hidden field (class HiddenField).
$form->addHidden('userid');
Use setNullable()
to change it to return null
instead of an empty string. The addFilter() allows you to change the submitted value.
Although the element is hidden, it is important to realize that its value can still be modified or spoofed by an attacker. Always thoroughly verify and validate all received values on the server side to prevent security risks associated with data manipulation.
addSubmit(string|int $name, $caption=null): SubmitButton
Adds submit button (class SubmitButton).
$form->addSubmit('submit', 'Register');
It is possible to have more than one submit button in the form:
$form->addSubmit('register', 'Register');
$form->addSubmit('cancel', 'Cancel');
To find out which of them was clicked, use:
if ($form['register']->isSubmittedBy()) {
// ...
}
If you don't want to validate the form when a submit button is pressed (such as Cancel or Preview buttons), you can turn it off with setValidationScope().
addButton(string|int $name, $caption): Button
Adds button (class Button) without submit function. It is useful for binding other functionality to id, for example a JavaScript action.
$form->addButton('raise', 'Raise salary')
->setHtmlAttribute('onclick', 'raiseSalary()');
addImageButton(string|int $name, ?string $src=null, ?string $alt=null): ImageButton
Adds submit button in form of an image (class ImageButton).
$form->addImageButton('submit', '/path/to/image');
When using multiple submit buttons, you can find out which one was clicked with
$form['submit']->isSubmittedBy()
.
The method was called addImage()
in version 3.0.
addContainer(string|int $name): Container
Adds a sub-form (class Container), or a container,
which can be treated the same way as a form. That means you can use methods like setDefaults()
or
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:');
The sent data is then returned as a multidimensional structure:
[
'first' => [
'name' => /* ... */,
'email' => /* ... */,
],
'second' => [
'name' => /* ... */,
'email' => /* ... */,
],
]
Overview of Settings
For all elements we can call the following methods (see API documentation for a complete overview):
setDefaultValue($value) |
sets the default value |
getValue() |
get current value |
setOmitted() |
omitted values |
setDisabled() |
disabling inputs |
Rendering:
setCaption($caption) |
change the caption of the item |
setTranslator($translator) |
sets translator |
setHtmlAttribute($name, $value) |
sets the HTML attribute of the element |
setHtmlId($id) |
sets the HTML attribute id |
setHtmlType($type) |
sets HTML attribute type |
setHtmlName($name) |
sets HTML attribute name |
setOption($key, $value) |
sets rendering data |
Validation:
setRequired() |
mandatory field |
addRule() |
set validation rule |
addCondition() , addConditionOn() |
set validation condition |
addError($message) |
passing error message |
The following methods can be called for the addText()
, addPassword()
, addTextArea()
,
addEmail()
, addInteger()
items:
setNullable() |
sets whether getValue() returns null instead of empty string |
setEmptyValue($value) |
sets the special value which is treated as empty string |
setMaxLength($length) |
sets the maximum number of allowed characters |
addFilter($filter) |
modifying Input Values |
Omitted Values
If you are not interested in the value entered by the user, we can use setOmitted()
to omit it from the result
provided by the $form->getValues()
method or passed to handlers. This is suitable for various passwords for
verification, antispam fields, etc.
$form->addPassword('passwordVerify', 'Password again:')
->setRequired('Fill your password again to check for typo')
->addRule($form::EQUAL, 'Password mismatch', $form['password'])
->setOmitted();
Disabling Inputs
Inputs can be disabled using setDisabled()
. A disabled input cannot be edited by the user.
$form->addText('username', 'User name:')
->setDisabled();
Disabled inputs are not sent to the server by the browser, so you won't find them in the data returned by the
$form->getValues()
function. However, if you set setOmitted(false)
, Nette will include their default
value in this data.
When setDisabled()
is called, the input's value is erased for security reasons. If you are setting a
default value, it is necessary to do so after its deactivation:
$form->addText('username', 'User name:')
->setDisabled()
->setDefaultValue($userName);
An alternative to disabled inputs are fields with the HTML readonly
attribute, which are sent to the server by the
browser. Although the field is only readable, it is important to realize that its value can still be modified or spoofed by
an attacker.
Custom Controls
Besides wide range of built-in form controls you can add custom controls to the form as follows:
$form->addComponent(new DateInput('Date:'), 'date');
// alternative syntax: $form['date'] = new DateInput('Date:');
There is a way to define new form methods for adding custom elements (eg $form->addZip()
). These are the
so-called extension methods. The downside is that code hints in editors won't work for them.
use Nette\Forms\Container;
// adds method 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, 'At least 5 numbers', '[0-9]{5}');
});
// usage
$form->addZip('zip', 'ZIP code:');
Low-Level Fields
To add an item to the form, you don't have to call $form->addXyz()
. Form items can be introduced exclusively in
templates instead. This is useful if you, for example, need to generate dynamic items:
{foreach $items as $item}
<p><input type=checkbox name="sel[]" value={$item->id}> {$item->name}</p>
{/foreach}
After submission, you can retrieve the values:
$data = $form->getHttpData($form::DATA_TEXT, 'sel[]');
$data = $form->getHttpData($form::DATA_TEXT | $form::DATA_KEYS, 'sel[]');
In the first parameter, you specify element type (DATA_FILE
for type=file
, DATA_LINE
for
one-line inputs like text
, password
or email
and DATA_TEXT
for the rest). The
second parameter matches HTML attribute name
. If you need to preserve keys, you can combine the first parameter with
DATA_KEYS
. This is useful for select
, radioList
or checkboxList
.
The getHttpData()
returns sanitized input. In this case, it will always be array of valid UTF-8 strings, no
matter what the attacker sent by the form. It's an alternative to working with $_POST
or $_GET
directly
if you want to receive safe data.