Элементы формы
Обзор стандартных элементов формы.
addText (string|int $name, $label=null, ?int $cols=null, ?int $maxLength=null): TextInput
Добавляет однострочное текстовое поле (класс TextInput). Если пользователь
не заполняет поле, возвращает пустую строку ''
, или с помощью
setNullable()
можно указать, чтобы возвращал null
.
$form->addText('name', 'Имя:')
->setRequired()
->setNullable();
Автоматически проверяет UTF-8, обрезает пробелы слева и справа и удаляет переводы строк, которые мог бы отправить злоумышленник.
Максимальную длину можно ограничить с помощью setMaxLength()
.
Изменить введенное пользователем значение позволяет addFilter().
С помощью setHtmlType()
можно изменить визуальный характер
текстового поля на типы, такие как search
, tel
или url
,
см. спецификацию.
Помните, что изменение типа является только визуальным и не заменяет
функцию валидации. Для типа url
рекомендуется добавить
специфическое правило валидации URL.
Для других типов ввода, таких как number
, range
,
email
, date
, datetime-local
, time
и color
,
используйте специализированные методы, такие как addInteger, addFloat, addEmail addDate, addTime, addDateTime и addColor, которые обеспечивают серверную валидацию. Типы
month
и week
пока не полностью поддерживаются во всех
браузерах.
Элементу можно установить так называемое empty-value, что-то вроде
значения по умолчанию, но если пользователь его не изменит, элемент
вернет пустую строку или null
.
$form->addText('phone', 'Телефон:')
->setHtmlType('tel')
->setEmptyValue('+7');
addTextArea (string|int $name, $label=null): TextArea
Добавляет поле для ввода многострочного текста (класс TextArea). Если пользователь не
заполняет поле, возвращает пустую строку ''
, или с помощью
setNullable()
можно указать, чтобы возвращал null
.
$form->addTextArea('note', 'Примечание:')
->addRule($form::MaxLength, 'Примечание слишком длинное', 10000);
Автоматически проверяет UTF-8 и нормализует разделители строк на
\n
. В отличие от однострочного поля ввода, обрезка пробелов не
происходит.
Максимальную длину можно ограничить с помощью setMaxLength()
.
Изменить введенное пользователем значение позволяет addFilter(). Можно установить так
называемое empty-value с помощью setEmptyValue()
.
addInteger (string|int $name, $label=null): TextInput
Добавляет поле для ввода целого числа (класс TextInput). Возвращает либо
integer, либо null
, если пользователь ничего не ввел.
$form->addInteger('year', 'Год:')
->addRule($form::Range, 'Год должен быть в диапазоне от %d до %d.', [1900, 2023]);
Элемент отображается как <input type="number">
. С помощью метода
setHtmlType()
можно изменить тип на range
для отображения в виде
ползунка, или на text
, если вы предпочитаете стандартное
текстовое поле без специального поведения типа number
.
addFloat (string|int $name, $label=null): TextInput
Добавляет поле для ввода десятичного числа (класс TextInput). Возвращает либо float,
либо null
, если пользователь ничего не ввел.
$form->addFloat('level', 'Уровень:')
->setDefaultValue(0)
->addRule($form::Range, 'Уровень должен быть в диапазоне от %d до %d.', [0, 100]);
Элемент отображается как <input type="number">
. С помощью метода
setHtmlType()
можно изменить тип на range
для отображения в виде
ползунка, или на text
, если вы предпочитаете стандартное
текстовое поле без специального поведения типа number
.
Nette и браузер Chrome принимают в качестве разделителя десятичных знаков
как запятую, так и точку. Чтобы эта функциональность была доступна и в
Firefox, рекомендуется установить атрибут lang
либо для данного
элемента, либо для всей страницы, например <html lang="ru">
.
addEmail (string|int $name, $label=null, int $maxLength=255): TextInput
Добавляет поле для ввода адреса электронной почты (класс TextInput). Если пользователь
не заполняет поле, возвращает пустую строку ''
, или с помощью
setNullable()
можно указать, чтобы возвращал null
.
$form->addEmail('email', 'E-mail:');
Проверяет, является ли значение действительным адресом электронной почты. Не проверяется, существует ли домен на самом деле, проверяется только синтаксис. Автоматически проверяет UTF-8, обрезает пробелы слева и справа.
Максимальную длину можно ограничить с помощью setMaxLength()
.
Изменить введенное пользователем значение позволяет addFilter(). Можно установить так
называемое empty-value с помощью setEmptyValue()
.
addPassword (string|int $name, $label=null, ?int $cols=null, ?int $maxLength=null): TextInput
Добавляет поле для ввода пароля (класс TextInput).
$form->addPassword('password', 'Пароль:')
->setRequired()
->addRule($form::MinLength, 'Пароль должен содержать не менее %d символов', 8)
->addRule($form::Pattern, 'Должен содержать цифру', '.*[0-9].*');
При повторном отображении формы поле будет пустым. Автоматически проверяет UTF-8, обрезает пробелы слева и справа и удаляет переводы строк, которые мог бы отправить злоумышленник.
addCheckbox (string|int $name, $caption=null): Checkbox
Добавляет флажок (чекбокс) (класс Checkbox). Возвращает значение
true
или false
, в зависимости от того, установлен ли флажок.
$form->addCheckbox('agree', 'Я согласен с условиями')
->setRequired('Необходимо согласиться с условиями');
addCheckboxList (string|int $name, $label=null, ?array $items=null): CheckboxList
Добавляет флажки для выбора нескольких элементов (класс CheckboxList). Возвращает
массив ключей выбранных элементов. Метод getSelectedItems()
возвращает
значения вместо ключей.
$form->addCheckboxList('colors', 'Цвета:', [
'r' => 'красный',
'g' => 'зеленый',
'b' => 'синий',
]);
Массив предлагаемых элементов передаем как третий параметр или
методом setItems()
.
С помощью setDisabled(['r', 'g'])
можно деактивировать отдельные
элементы.
Элемент автоматически проверяет, не произошла ли подделка и что
выбранные элементы действительно являются одними из предлагаемых и не
были деактивированы. Методом getRawValue()
можно получить
отправленные элементы без этой важной проверки.
При установке выбранных по умолчанию элементов также проверяет, что
они являются одними из предлагаемых, иначе выбрасывает исключение. Эту
проверку можно отключить с помощью checkDefaultValue(false)
.
Если вы отправляете форму методом GET
, вы можете выбрать более
компактный способ передачи данных, который экономит размер строки
запроса. Он активируется установкой HTML-атрибута формы:
$form->setHtmlAttribute('data-nette-compact');
addRadioList (string|int $name, $label=null, ?array $items=null): RadioList
Добавляет переключатели (радиокнопки) (класс RadioList). Возвращает ключ
выбранного элемента или null
, если пользователь ничего не выбрал.
Метод getSelectedItem()
возвращает значение вместо ключа.
$sex = [
'm' => 'мужчина',
'f' => 'женщина',
];
$form->addRadioList('gender', 'Пол:', $sex);
Массив предлагаемых элементов передаем как третий параметр или
методом setItems()
.
С помощью setDisabled(['m', 'f'])
можно деактивировать отдельные
элементы.
Элемент автоматически проверяет, не произошла ли подделка и что
выбранный элемент действительно является одним из предлагаемых и не
был деактивирован. Методом getRawValue()
можно получить отправленный
элемент без этой важной проверки.
При установке выбранного по умолчанию элемента также проверяет, что
он является одним из предлагаемых, иначе выбрасывает исключение. Эту
проверку можно отключить с помощью checkDefaultValue(false)
.
addSelect (string|int $name, $label=null, ?array $items=null, ?int $size=null): SelectBox
Добавляет выпадающий список (select box) (класс SelectBox). Возвращает ключ
выбранного элемента или null
, если пользователь ничего не выбрал.
Метод getSelectedItem()
возвращает значение вместо ключа.
$countries = [
'CZ' => 'Чешская Республика',
'SK' => 'Словакия',
'RU' => 'Россия',
];
$form->addSelect('country', 'Страна:', $countries)
->setDefaultValue('RU');
Массив предлагаемых элементов передаем как третий параметр или
методом setItems()
. Элементы могут быть и двумерным массивом:
$countries = [
'Европа' => [
'CZ' => 'Чешская Республика',
'SK' => 'Словакия',
'GB' => 'Великобритания',
],
'RU' => 'Россия',
'US' => 'США',
'?' => 'другая',
];
У выпадающих списков часто первый элемент имеет особое значение,
служит призывом к действию. Для добавления такого элемента служит
метод setPrompt()
.
$form->addSelect('country', 'Страна:', $countries)
->setPrompt('Выберите страну');
С помощью setDisabled(['CZ', 'SK'])
можно деактивировать отдельные
элементы.
Элемент автоматически проверяет, не произошла ли подделка и что
выбранный элемент действительно является одним из предлагаемых и не
был деактивирован. Методом getRawValue()
можно получить отправленный
элемент без этой важной проверки.
При установке выбранного по умолчанию элемента также проверяет, что
он является одним из предлагаемых, иначе выбрасывает исключение. Эту
проверку можно отключить с помощью checkDefaultValue(false)
.
addMultiSelect (string|int $name, $label=null, ?array $items=null, ?int $size=null): MultiSelectBox
Добавляет выпадающий список для выбора нескольких элементов (класс MultiSelectBox). Возвращает
массив ключей выбранных элементов. Метод getSelectedItems()
возвращает
значения вместо ключей.
$form->addMultiSelect('countries', 'Страны:', $countries);
Массив предлагаемых элементов передаем как третий параметр или
методом setItems()
. Элементы могут быть и двумерным массивом.
С помощью setDisabled(['CZ', 'SK'])
можно деактивировать отдельные
элементы.
Элемент автоматически проверяет, не произошла ли подделка и что
выбранные элементы действительно являются одними из предлагаемых и не
были деактивированы. Методом getRawValue()
можно получить
отправленные элементы без этой важной проверки.
При установке выбранных по умолчанию элементов также проверяет, что
они являются одними из предлагаемых, иначе выбрасывает исключение. Эту
проверку можно отключить с помощью checkDefaultValue(false)
.
addUpload (string|int $name, $label=null): UploadControl
Добавляет поле для загрузки файла (класс UploadControl). Возвращает
объект FileUpload, даже если
пользователь не отправил ни одного файла, что можно проверить методом
FileUpload::hasFile()
.
$form->addUpload('avatar', 'Аватар:')
->addRule($form::Image, 'Аватар должен быть в формате JPEG, PNG, GIF, WebP или AVIF.')
->addRule($form::MaxFileSize, 'Максимальный размер 1 МБ.', 1024 * 1024);
Если файл не удается корректно загрузить, форма не отправляется
успешно и отображается ошибка. То есть при успешной отправке нет
необходимости проверять метод FileUpload::isOk()
.
Никогда не доверяйте оригинальному имени файла, возвращаемому
методом FileUpload::getName()
, клиент мог отправить вредоносное имя файла
с целью повредить или взломать ваше приложение.
Правила MimeType
и Image
определяют требуемый тип на основе
сигнатуры файла и не проверяют его целостность. Не повреждено ли
изображение, можно выяснить, например, попытавшись его загрузить.
addMultiUpload (string|int $name, $label=null): UploadControl
Добавляет поле для загрузки нескольких файлов одновременно (класс UploadControl). Возвращает
массив объектов FileUpload. Метод
FileUpload::hasFile()
у каждого из них будет возвращать true
.
$form->addMultiUpload('files', 'Файлы:')
->addRule($form::MaxLength, 'Максимально можно загрузить %d файлов', 10);
Если какой-либо файл не удается корректно загрузить, форма не
отправляется успешно и отображается ошибка. То есть при успешной
отправке нет необходимости проверять метод FileUpload::isOk()
.
Никогда не доверяйте оригинальным именам файлов, возвращаемым
методом FileUpload::getName()
, клиент мог отправить вредоносное имя файла
с целью повредить или взломать ваше приложение.
Правила MimeType
и Image
определяют требуемый тип на основе
сигнатуры файла и не проверяют его целостность. Не повреждено ли
изображение, можно выяснить, например, попытавшись его загрузить.
addDate (string|int $name, $label=null): DateTimeControl
Добавляет поле, которое позволяет пользователю легко ввести дату, состоящую из года, месяца и дня (класс DateTimeControl).
В качестве значения по умолчанию принимает либо объекты, реализующие
интерфейс DateTimeInterface
, строку с временем, либо число,
представляющее UNIX timestamp. То же самое относится к аргументам правил
Min
, Max
или Range
, которые определяют минимальную и
максимальную допустимую дату.
$form->addDate('date', 'Дата:')
->setDefaultValue(new DateTime)
->addRule($form::Min, 'Дата должна быть не ранее месяца назад.', new DateTime('-1 month'));
По умолчанию возвращает объект DateTimeImmutable
, методом
setFormat()
вы можете указать текстовый формат
или timestamp:
$form->addDate('date', 'Дата:')
->setFormat('Y-m-d');
addTime (string|int $name, $label=null, bool $withSeconds=false): DateTimeControl
Добавляет поле, которое позволяет пользователю легко ввести время, состоящее из часов, минут и, опционально, секунд (класс DateTimeControl).
В качестве значения по умолчанию принимает либо объекты, реализующие
интерфейс DateTimeInterface
, строку с временем, либо число,
представляющее UNIX timestamp. Из этих входных данных используется только
информация о времени, дата игнорируется. То же самое относится к
аргументам правил Min
, Max
или Range
, которые
определяют минимальное и максимальное допустимое время. Если
установленное минимальное значение выше максимального, создается
временной диапазон, пересекающий полночь.
$form->addTime('time', 'Время:', withSeconds: true)
->addRule($form::Range, 'Время должно быть в диапазоне от %s до %s.', ['12:30', '13:30']);
По умолчанию возвращает объект DateTimeImmutable
(с датой 1 января
1 года), методом setFormat()
вы можете указать текстовый
формат:
$form->addTime('time', 'Время:')
->setFormat('H:i');
addDateTime (string|int $name, $label=null, bool $withSeconds=false): DateTimeControl
Добавляет поле, которое позволяет пользователю легко ввести дату и время, состоящие из года, месяца, дня, часов, минут и, опционально, секунд (класс DateTimeControl).
В качестве значения по умолчанию принимает либо объекты, реализующие
интерфейс DateTimeInterface
, строку с временем, либо число,
представляющее UNIX timestamp. То же самое относится к аргументам правил
Min
, Max
или Range
, которые определяют минимальную и
максимальную допустимую дату.
$form->addDateTime('datetime', 'Дата и время:')
->setDefaultValue(new DateTime)
->addRule($form::Min, 'Дата должна быть не ранее месяца назад.', 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
Добавляет поле для выбора цвета (класс ColorPicker). Цвет — это
строка в формате #rrggbb
. Если пользователь не сделал выбор,
возвращается черный цвет #000000
.
$form->addColor('color', 'Цвет:')
->setDefaultValue('#3C8ED7');
addHidden (string|int $name, ?string $default=null): HiddenField
Добавляет скрытое поле (класс HiddenField).
$form->addHidden('userid');
С помощью setNullable()
можно настроить, чтобы возвращался null
вместо пустой строки. Изменить отправленное значение позволяет addFilter().
Хотя элемент скрыт, важно помнить, что значение все еще может быть изменено или подделано злоумышленником. Всегда тщательно проверяйте и валидируйте все полученные значения на стороне сервера, чтобы предотвратить риски безопасности, связанные с манипуляцией данными.
addSubmit (string|int $name, $caption=null): SubmitButton
Добавляет кнопку отправки (класс SubmitButton).
$form->addSubmit('submit', 'Отправить');
В форме может быть несколько кнопок отправки:
$form->addSubmit('register', 'Зарегистрироваться');
$form->addSubmit('cancel', 'Отмена');
Чтобы определить, какая из них была нажата, используйте:
if ($form['register']->isSubmittedBy()) {
// ...
}
Если вы не хотите валидировать всю форму при нажатии кнопки (например, для кнопок Отмена или Предпросмотр), используйте setValidationScope().
addButton (string|int $name, $caption): Button
Добавляет кнопку (класс Button), которая не имеет функции отправки. Ее можно использовать для какой-либо другой функции, например, вызова JavaScript-функции при нажатии.
$form->addButton('raise', 'Повысить зарплату')
->setHtmlAttribute('onclick', 'raiseSalary()');
addImageButton (string|int $name, ?string $src=null, ?string $alt=null): ImageButton
Добавляет кнопку отправки в виде изображения (класс ImageButton).
$form->addImageButton('submit', '/path/to/image');
При использовании нескольких кнопок отправки можно определить,
какая была нажата, с помощью $form['submit']->isSubmittedBy()
.
addContainer (string|int $name): Container
Добавляет подформу (класс Container), или контейнер, в который
можно добавлять другие элементы так же, как мы добавляем их в форму.
Работают также методы setDefaults()
или getValues()
.
$sub1 = $form->addContainer('first');
$sub1->addText('name', 'Ваше имя:');
$sub1->addEmail('email', 'Email:');
$sub2 = $form->addContainer('second');
$sub2->addText('name', 'Ваше имя:');
$sub2->addEmail('email', 'Email:');
Отправленные данные затем возвращаются в виде многомерной структуры:
[
'first' => [
'name' => /* ... */,
'email' => /* ... */,
],
'second' => [
'name' => /* ... */,
'email' => /* ... */,
],
]
Обзор настроек
Для всех элементов мы можем вызывать следующие методы (полный обзор в документации API):
setDefaultValue($value) |
устанавливает значение по умолчанию |
getValue() |
получить текущее значение |
setOmitted() |
Исключение значения |
setDisabled() |
Деактивация элементов |
Отображение:
setCaption($caption) |
изменяет метку элемента |
setTranslator($translator) |
устанавливает переводчик |
setHtmlAttribute($name, $value) |
устанавливает HTML атрибут элемента |
setHtmlId($id) |
устанавливает HTML атрибут id |
setHtmlType($type) |
устанавливает HTML атрибут type |
setHtmlName($name) |
устанавливает HTML атрибут name |
setOption($key, $value) |
настройки для отображения |
Валидация:
setRequired() |
обязательный элемент |
addRule() |
установка правила валидации |
addCondition() , addConditionOn() |
установка условия валидации |
addError($message) |
передача сообщения об ошибке |
Для элементов addText()
, addPassword()
, addTextArea()
,
addEmail()
, addInteger()
можно вызывать следующие методы:
setNullable() |
устанавливает, вернет ли getValue() null вместо пустой строки |
setEmptyValue($value) |
устанавливает специальное значение, которое считается пустой строкой |
setMaxLength($length) |
устанавливает максимальное количество разрешенных символов |
addFilter($filter) |
изменение ввода |
Исключение значения
Если нас не интересует значение, введенное пользователем, мы можем с
помощью setOmitted()
исключить его из результата метода
$form->getValues()
или из данных, передаваемых в обработчики. Это
удобно для различных паролей для проверки, антиспам-элементов и т. д.
$form->addPassword('passwordVerify', 'Пароль для проверки:')
->setRequired('Пожалуйста, введите пароль еще раз для проверки')
->addRule($form::Equal, 'Пароли не совпадают', $form['password'])
->setOmitted();
Деактивация элементов
Элементы можно деактивировать с помощью setDisabled()
. Такой
элемент пользователь не может редактировать.
$form->addText('username', 'Имя пользователя:')
->setDisabled();
Отключенные элементы браузер вообще не отправляет на сервер, поэтому
их не найти в данных, возвращаемых функцией $form->getValues()
. Однако,
если вы установите setOmitted(false)
, Nette включит в эти данные их
значение по умолчанию.
При вызове setDisabled()
из соображений безопасности значение
элемента удаляется. Если вы устанавливаете значение по умолчанию,
это необходимо делать после его деактивации:
$form->addText('username', 'Имя пользователя:')
->setDisabled()
->setDefaultValue($userName);
Альтернативой отключенным элементам являются элементы с
HTML-атрибутом readonly
, которые браузер отправляет на сервер. Хотя
элемент предназначен только для чтения, важно помнить, что его
значение все еще может быть изменено или подделано злоумышленником.
Пользовательские элементы
Помимо широкого спектра встроенных элементов формы, вы можете добавлять в форму пользовательские элементы следующим образом:
$form->addComponent(new DateInput('Дата:'), 'date');
// альтернативный синтаксис: $form['date'] = new DateInput('Дата:');
Форма является потомком класса Container, а отдельные элементы — потомками Component.
Существует способ определить новые методы формы, служащие для
добавления пользовательских элементов (например, $form->addZip()
).
Это так называемые extension methods. Недостаток в том, что для них не будет
работать автодополнение в редакторах.
use Nette\Forms\Container;
// добавим метод 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, 'Не менее 5 цифр', '[0-9]{5}');
});
// использование
$form->addZip('zip', 'Почтовый индекс:');
Низкоуровневые элементы
Можно использовать и элементы, которые мы записываем только в
шаблоне и не добавляем в форму каким-либо из методов $form->addXyz()
.
Например, когда мы выводим записи из базы данных и заранее не знаем,
сколько их будет и какие у них будут ID, и хотим у каждой строки
отобразить чекбокс или радиокнопку, достаточно закодировать это в
шаблоне:
{foreach $items as $item}
<p><input type=checkbox name="sel[]" value={$item->id}> {$item->name}</p>
{/foreach}
А после отправки узнать значение:
$data = $form->getHttpData($form::DataText, 'sel[]');
$data = $form->getHttpData($form::DataText | $form::DataKeys, 'sel[]');
где первый параметр — это тип элемента (DataFile
для type=file
,
DataLine
для однострочных вводов, таких как text
, password
,
email
и т. д., и DataText
для всех остальных), а второй параметр
sel[]
соответствует HTML-атрибуту name. Тип элемента можно
комбинировать со значением DataKeys
, которое сохраняет ключи
элементов. Это особенно полезно для select
, radioList
и
checkboxList
.
Существенно то, что getHttpData()
возвращает санитайзенное
значение, в данном случае это всегда будет массив валидных UTF-8 строк,
независимо от того, что попытался бы подсунуть серверу злоумышленник.
Это аналог прямой работы с $_POST
или $_GET
, но с тем
существенным отличием, что всегда возвращаются чистые данные, так, как
вы привыкли у стандартных элементов форм Nette.