Елементи форми

Огляд стандартних елементів форми.

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

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="uk">.

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' => 'Словаччина',
	'GB' => 'Велика Британія',
];

$form->addSelect('country', 'Країна:', $countries)
	->setDefaultValue('SK');

Масив пропонованих елементів передаємо як третій параметр або методом setItems(). Елементи також можуть бути двовимірним масивом:

$countries = [
	'Європа' => [
		'CZ' => 'Чеська Республіка',
		'SK' => 'Словаччина',
		'GB' => 'Велика Британія',
	],
	'CA' => 'Канада',
	'US' => 'США',
	'?'  => 'інша',
];

У select box-ах часто перший елемент має особливе значення, служить як заклик до дії. Для додавання такого елемента служить метод 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

Додає select box для вибору кількох елементів (клас 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, 'Час має бути в діапазоні від %d до %d.', ['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'));

Стандартно повертає об'єкт DateTimeImmutable, методом setFormat() ви можете вказати текстовий формат або 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.

версія: 4.0