Form Controls

Overview of standard form controls.

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

Adds a single-line text input field (class TextInput). If the user does not fill in the field, it returns an empty string '', or use setNullable() to make it return null instead.

$form->addText('name', 'Name:')
	->setRequired()
	->setNullable();

Automatically validates UTF-8, trims leading and trailing whitespace, and removes line breaks that could be sent by an attacker.

The maximum length can be limited using setMaxLength(). The addFilter() method allows modifying the value entered by the user.

Using setHtmlType(), you can change the visual appearance of the text field to types like search, tel, or url as defined in the specification. Remember that changing the type is purely visual and does not replace validation functionality. For the url type, it's advisable to add a specific URL validation rule.

For other input types like number, range, email, date, datetime-local, time, and color, use specialized methods such as addInteger, addFloat, addEmail, addDate, addTime, addDateTime, and addColor, which provide server-side validation. The types month and week are not yet fully supported by all browsers.

An “empty value” can be set for the control. This acts somewhat like a default value, but if the user doesn't change it, the control returns an empty string or null.

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

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

Adds a multi-line text input field (class TextArea). If the user doesn't fill in the field, it returns an empty string '', or use setNullable() to make it return null instead.

$form->addTextArea('note', 'Note:')
	->addRule($form::MaxLength, 'Your note is way too long', 10000);

Automatically validates UTF-8 and normalizes line endings to \n. Unlike the single-line input field, no whitespace trimming occurs.

The maximum length can be limited using setMaxLength(). The addFilter() method allows modifying the user-entered value. An empty value can be set using setEmptyValue().

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

Adds an input field for entering an integer (class TextInput). Returns either an integer or null if the user enters nothing.

$form->addInteger('year', 'Year:')
	->addRule($form::Range, 'The year must be between %d and %d.', [1900, 2023]);

The control renders as <input type="number">. 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 the number type.

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

Adds an input field for entering a floating-point number (class TextInput). Returns either a float or null if the user enters nothing.

$form->addFloat('level', 'Level:')
	->setDefaultValue(0.0) // Explicitly set float default
	->addRule($form::Range, 'The level must be between %f and %f.', [0.0, 100.0]); // Use float range and %f

The control renders as <input type="number">. 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 the number type.

Nette and the Chrome browser accept both a comma and a dot as decimal separators. To enable this functionality in Firefox as well, it is recommended to set the lang attribute either for the specific control or for the entire page, for example, <html lang="en">.

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

Adds an input field for entering an email address (class TextInput). If the user doesn't fill in the field, it returns an empty string '', or use setNullable() to make it return null instead.

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

Validates that the value is a valid email address. It does not check if the domain actually exists, only the syntax is verified. Automatically validates UTF-8 and trims leading and trailing whitespace.

The maximum length can be limited using setMaxLength(). The addFilter() method allows modifying the user-entered value. An empty value can be set using setEmptyValue().

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

Adds a password input field (class TextInput).

$form->addPassword('password', 'Password:')
	->setRequired()
	->addRule($form::MinLength, 'Password must be at least %d characters long', 8)
	->addRule($form::Pattern, 'Password must contain a number', '.*[0-9].*');

When the form is redisplayed, the field will be empty. Automatically validates UTF-8, trims leading and trailing whitespace, and removes line breaks that could be sent by an attacker.

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

Adds a checkbox (class Checkbox). Returns 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 a list of checkboxes for selecting multiple items (class CheckboxList). Returns an array of the keys of the selected items. The getSelectedItems() method returns the values instead of keys.

$form->addCheckboxList('colors', 'Colors:', [
	'r' => 'red',
	'g' => 'green',
	'b' => 'blue',
]);

Pass the array of offered items as the third parameter or using the setItems() method.

Use setDisabled(['r', 'g']) to disable individual items.

The control automatically checks that no forgery occurred and that the selected items are indeed among the offered ones and were not disabled. The getRawValue() method can be used to retrieve submitted items without this important check.

When setting default selected items, it also checks that they are among the offered ones, otherwise it throws an exception. This check can be disabled using checkDefaultValue(false).

If you are submitting the form using the GET method, you can choose a more compact data transfer method that saves query string size. Activate it by setting an HTML attribute on 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 selected nothing. The getSelectedItem() method returns the value instead of the key.

$sex = [
	'm' => 'male',
	'f' => 'female',
];
$form->addRadioList('gender', 'Gender:', $sex);

Pass the array of offered items as the third parameter or using the setItems() method.

Use setDisabled(['m']) to disable individual items.

The control automatically checks that no forgery occurred and that the selected item is indeed one of the offered ones and was not disabled. The getRawValue() method can be used to retrieve the submitted item without this important check.

When setting the default selected item, it also checks that it is one of the offered ones, otherwise it throws an exception. This check can be disabled using checkDefaultValue(false).

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

Adds a select box (class SelectBox). Returns the key of the selected item, or null if the user selected nothing. The getSelectedItem() method returns the value instead of the key.

$countries = [
	'CZ' => 'Czech Republic',
	'SK' => 'Slovakia',
	'GB' => 'United Kingdom',
];

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

Pass the array of offered items as the third parameter or using the setItems() method. Items can also be a two-dimensional array (representing optgroups):

$countries = [
	'Europe' => [
		'CZ' => 'Czech Republic',
		'SK' => 'Slovakia',
		'GB' => 'United Kingdom',
	],
	'CA' => 'Canada',
	'US' => 'USA',
	'?'  => 'other',
];

In select boxes, the first item often has a special meaning, serving as a prompt to action. Use the setPrompt() method to add such an item.

$form->addSelect('country', 'Country:', $countries)
	->setPrompt('Choose a country');

Use setDisabled(['CZ', 'SK']) to disable individual items.

The control automatically checks that no forgery occurred and that the selected item is indeed one of the offered ones and was not disabled. The getRawValue() method can be used to retrieve the submitted item without this important check.

When setting the default selected item, it also checks that it is one of the offered ones, otherwise it throws an exception. This check can be disabled using checkDefaultValue(false).

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

Adds a select box for selecting multiple items (class MultiSelectBox). Returns an array of the keys of the selected items. The getSelectedItems() method returns the values instead of keys.

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

Pass the array of offered items as the third parameter or using the setItems() method. Items can also be a two-dimensional array.

Use setDisabled(['CZ', 'SK']) to disable individual items.

The control automatically checks that no forgery occurred and that the selected items are indeed among the offered ones and were not disabled. The getRawValue() method can be used to retrieve submitted items without this important check.

When setting default selected items, it also checks that they are among the offered ones, otherwise it throws an exception. This check can be disabled using checkDefaultValue(false).

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

Adds a file upload field (class UploadControl). Returns a FileUpload object, even if the user did not upload any file, which can be checked using the FileUpload::hasFile() method.

$form->addUpload('avatar', 'Avatar:')
	->addRule($form::Image, 'Avatar must be JPEG, PNG, GIF, WebP or AVIF.')
	->addRule($form::MaxFileSize, 'Maximum size is 1 MB.', 1024 * 1024);

If the file fails to upload correctly, the form is not successfully submitted, and an error is displayed. That is, upon successful submission, it is not necessary to check the FileUpload::isOk() method.

Never trust the original file name returned by the FileUpload::getName() method; the client could have sent a malicious file name with the intent to damage or hack your application.

The MimeType and Image rules detect the required type based on the file's signature and do not verify its integrity. Whether an image is corrupted can be determined, for example, by attempting to load it.

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

Adds a field for uploading multiple files at once (class UploadControl). Returns an array of FileUpload objects. The FileUpload::hasFile() method for each of them will return true.

$form->addMultiUpload('files', 'Files:')
	->addRule($form::MaxLength, 'Maximum of %d files can be uploaded.', 10); // Added period

If any file fails to upload correctly, the form is not successfully submitted, and an error is displayed. That is, upon successful submission, it is not necessary to check the FileUpload::isOk() method for each file.

Never trust the original file names returned by the FileUpload::getName() method; the client could have sent malicious file names with the intent to damage or hack your application.

The MimeType and Image rules detect the required type based on the file's signature and do not verify its integrity. Whether an image is corrupted can be determined, for example, by attempting to load it.

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

Adds a field that allows the user to easily enter a date consisting of year, month, and day (class DateTimeControl).

As a default value, it accepts objects implementing the DateTimeInterface, a string containing time, or a number representing a UNIX timestamp. The same applies to the arguments of the Min, Max, or Range rules, which define the minimum and maximum allowed dates.

$form->addDate('date', 'Date:')
	->setDefaultValue(new DateTime)
	->addRule($form::Min, 'The date must be at least one month old.', new DateTime('-1 month'));

By default, it returns a DateTimeImmutable object. Using the setFormat() method, you can specify a text format or a 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 enter a time consisting of hours, minutes, and optionally seconds (class DateTimeControl).

As a default value, it accepts objects implementing the DateTimeInterface, a string containing 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 arguments of the Min, Max, or Range rules, which define the minimum and maximum allowed times. If the set minimum value 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 %s and %s.', ['12:30', '13:30']); // Use %s for time strings

By default, it returns a DateTimeImmutable object (with the date set to January 1, year 1). 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 enter both date and time, consisting of year, month, day, hours, minutes, and optionally seconds (class DateTimeControl).

As a default value, it accepts objects implementing the DateTimeInterface, a string containing time, or a number representing a UNIX timestamp. The same applies to the arguments of the Min, Max, or Range rules, which define the minimum and maximum allowed date and time.

$form->addDateTime('datetime', 'Date and Time:')
	->setDefaultValue(new DateTime)
	->addRule($form::Min, 'The date must be at least one month old.', new DateTime('-1 month'));

By default, it returns a DateTimeImmutable object. Using the setFormat() method, you can specify a text format or a timestamp:

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

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

Adds a color picker field (class ColorPicker). The color is returned as a string in the format #rrggbb. If the user does not make a selection, it returns black #000000.

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

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

Adds a hidden field (class HiddenField).

$form->addHidden('userid');

Use setNullable() to make it return null instead of an empty string. The addFilter() method allows modifying the submitted value.

Although the control 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 a submit button (class SubmitButton).

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

It is possible to have more than one submit button in the form:

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

To determine which one was clicked, use:

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

If you do not want to validate the entire form when a button is pressed (for example, for Cancel or Preview buttons), use setValidationScope().

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

Adds a button (class Button) that does not have a submit function. It can therefore be used for other functions, e.g., calling a JavaScript function on click.

$form->addButton('raise', 'Raise salary')
	->setHtmlAttribute('onclick', 'raiseSalary()');

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

Adds a submit button in the form of an image (class ImageButton).

$form->addImageButton('submit', '/path/to/image.png', 'Submit');

When using multiple submit buttons, you can determine which one was clicked using $form['submit']->isSubmittedBy().

addContainer (string|int $name): Container

Adds a sub-form (class Container), or a container, into which other controls can be added in the same way as they are added to the form. Methods like setDefaults() or getValues() work as well.

$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 submitted data is then returned as a multi-dimensional structure:

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

Overview of Settings

For all controls, we can call the following methods (see the API documentation for a complete overview):

setDefaultValue($value) sets the default value
getValue() get the current value
setOmitted() Omitted Values
setDisabled() Disabling Inputs

Rendering:

setCaption($caption) changes the control's label
setTranslator($translator) sets the translator
setHtmlAttribute($name, $value) sets an HTML attribute for the element
setHtmlId($id) sets the HTML attribute id
setHtmlType($type) sets the HTML attribute type
setHtmlName($name) sets the HTML attribute name
setOption($key, $value) sets rendering options

Validation:

setRequired() makes the control required
addRule() adds a validation rule
addCondition(), addConditionOn() sets a validation condition
addError($message) adds an error message

For controls addText(), addPassword(), addTextArea(), addEmail(), addInteger(), the following methods can be called:

setNullable() sets whether getValue() returns null instead of an empty string
setEmptyValue($value) sets a special value that is considered an empty string
setMaxLength($length) sets the maximum allowed number of characters
addFilter($filter) modifies input

Omitted Values

If we are not interested in the value filled in by the user, we can use setOmitted() to exclude it from the result of the $form->getValues() method or from the data passed to handlers. This is useful for various password confirmation fields, anti-spam controls, etc.

$form->addPassword('passwordVerify', 'Password again:')
	->setRequired('Fill your password again to check for typo')
	->addRule($form::Equal, 'Passwords do not match', $form['password'])
	->setOmitted();

Disabling Inputs

Controls can be disabled using setDisabled(). A disabled control cannot be edited by the user.

$form->addText('username', 'User name:')
	->setDisabled();

Disabled controls are not sent by the browser to the server at all, 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 control's value is cleared for security reasons. If you are setting a default value, it is necessary to do so after disabling it:

$form->addText('username', 'User name:')
	->setDisabled()
	->setDefaultValue($userName);

An alternative to disabled controls are controls with the HTML readonly attribute, which the browser does send to the server. Although the control is read-only, it is important to realize that its value can still be modified or spoofed by an attacker.

Custom Controls

Besides the wide range of built-in form controls, you can add custom controls to the form in this way:

$form->addComponent(new DateInput('Date:'), 'date');
// alternative syntax: $form['date'] = new DateInput('Date:');

The form is a descendant of the Container class, and individual controls are descendants of the Component class.

There is a way to define new form methods for adding custom controls (e.g., $form->addZip()). These are called extension methods. The disadvantage is that code completion in editors will not 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

It's also possible to use controls that are only written in the template and not added to the form using any of the $form->addXyz() methods. For example, when listing records from a database where we don't know in advance how many there will be or what their IDs will be, and we want to display a checkbox or radio button for each row, we can simply code it in the template:

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

And after submission, we retrieve the value:

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

where the first parameter is the element type (DataFile for type=file, DataLine for single-line inputs like text, password, email, etc., and DataText for all others) and the second parameter sel[] corresponds to the HTML name attribute. We can combine the element type with the DataKeys value, which preserves the keys of the elements. This is particularly useful for select, radioList, and checkboxList.

Crucially, getHttpData() returns a sanitized value. In this case, it will always be an array of valid UTF-8 strings, regardless of what an attacker might try to submit to the server. This is analogous to working directly with $_POST or $_GET, but with the significant difference that it always returns clean data, just as you are accustomed to with standard Nette form controls.

version: 4.0 3.x 2.x