Елементи на формуляр
Преглед на стандартните елементи на формуляр.
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('+359');
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="bg">
.
addEmail (string|int $name, $label=null, int $maxLength=255): TextInput
Добавя поле за въвеждане на имейл адрес (клас TextInput). Ако потребителят не
попълни полето, връща празен низ ''
, или чрез setNullable()
може
да се укаже да връща null
.
$form->addEmail('email', 'Имейл:');
Оверява дали стойността е валиден имейл адрес. Не се проверява дали домейнът действително съществува, проверява се само синтаксисът. Автоматично валидира 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
, можете да изберете
по-компактен начин за пренос на данни, който спестява размер на query
string-а. Активира се чрез задаване на 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
Добавя селект бокс (клас SelectBox). Връща ключа на
избрания елемент, или null
, ако потребителят не е избрал нищо.
Методът getSelectedItem()
връща стойността вместо ключа.
$countries = [
'BG' => 'България',
'CZ' => 'Чешка република',
'SK' => 'Словакия',
];
$form->addSelect('country', 'Държава:', $countries)
->setDefaultValue('BG');
Масивът с предлаганите елементи предаваме като трети параметър или
чрез метода setItems()
. Елементите могат да бъдат и
двумерен масив:
$countries = [
'Европа' => [
'BG' => 'България',
'CZ' => 'Чешка република',
'SK' => 'Словакия',
],
'CA' => 'Канада',
'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 MB.', 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'));
Стандартно връща обект 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', 'Имейл:');
$sub2 = $form->addContainer('second');
$sub2->addText('name', 'Вашето име:');
$sub2->addEmail('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 формулярите.