Изобразяване на форми
Външният вид на формите може да бъде много разнообразен. На практика
можем да се сблъскаме с две крайности. От една страна, има нужда от
визуализиране на поредица от формуляри в дадено приложение, които
визуално си приличат един на друг, и оценяваме лесното визуализиране
без шаблон с помощта на $form->render()
. Такъв обикновено е случаят с
административните интерфейси.
От друга страна, има различни формуляри, в които всеки един е уникален. Техният външен вид се описва най-добре с помощта на езика HTML в шаблона. И разбира се, освен двете споменати крайности, ще срещнем много форми, които попадат някъде по средата.
Рендъринг с Latte
Системата за шаблони Latte улеснява значително изчертаването на форми и техните елементи. Първо ще ви покажем как да визуализирате формулярите ръчно, елемент по елемент, за да получите пълен контрол върху кода. По-късно ще ви покажем как да автоматизирате такова визуализиране.
Можете да имате предложение за шаблон Latte за формуляра,
генериран чрез метода Nette\Forms\Blueprint::latte($form)
, който ще го изведе на
страницата на браузъра. След това просто трябва да изберете кода с едно
щракване и да го копирате в проекта си.
{control}
Най-лесният начин за показване на формуляр е да го запишете в шаблон:
Външният вид на визуализираната форма може да бъде променен чрез персонализиране на Renderer и отделните контроли.
n:name
Много е лесно да свържете дефиницията на формуляра в кода на PHP с кода
на HTML. Просто добавете атрибутите n:name
. Толкова е лесно!
Външният вид на получения HTML код е изцяло във ваши ръце. Ако
използвате атрибута n:name
с <select>
, <button>
или
<textarea>
елементи, вътрешното им съдържание ще бъде попълнено
автоматично. Освен това етикетът <form n:name>
създава локална
променлива $form
с нарисуван обект на формата, а затварящият таг
</form>
прерисува всички ненарисувани скрити елементи (същото
важи и за {form} ... {/form}
).
Не забравяйте обаче да изведете възможните съобщения за грешки.
Както тези, добавени към отделните елементи чрез метода addError()
(с
помощта на {inputError}
), така и тези, добавени директно към формуляра
(върнати от метода $form->getOwnErrors()
):
По-сложните елементи на формуляра, като например RadioList или CheckboxList, могат да се показват елемент по елемент:
{label}
{input}
Не искате ли да мислите за всеки елемент кой HTML елемент да използвате
за него в шаблона? <input>
, <textarea>
и т.н.? Решението е
универсалният етикет {input}
:
Ако формулярът използва преводач, текстът в таговете {label}
ще
бъде преведен.
По-сложните елементи на формуляра, като например RadioList или CheckboxList, могат да се визуализират елемент по елемент:
За показване на <input>
в елемента Checkbox използвайте
{input myCheckbox:}
. HTML атрибутите трябва да бъдат разделени със запетая
{input myCheckbox:, class: required}
.
{inputError}
Извежда съобщение за грешка за елемента на формата, ако има такова.
Съобщението обикновено е обвито в HTML елемент за целите на
стилизирането. Избягвайте да показвате празен елемент, ако няма
съобщение, като използвате n:ifcontent
:
Можем да открием наличието на грешка с помощта на метода
hasErrors()
и да зададем съответния клас на родителския елемент:
{form}
Етикети {form signInForm}...{/form}
са алтернатива на
<form n:name="signInForm">...</form>
.
Автоматично визуализиране
С помощта на таговете {input}
и {label}
можем лесно да
създадем общ шаблон за всяка форма. Тя ще извърши итерация и ще
изобрази последователно всички елементи на формуляра, с изключение на
скритите елементи, които се изобразяват автоматично при завършване на
формуляра с помощта на </form>
етикет. Той ще очаква името на
визуализираната форма в променливата $form
.
Сдвоените самозатварящи се тагове {label .../}
се използват за
показване на таговете, идващи от дефиницията на формуляра в PHP кода.
Можете да запазите този общ шаблон в basic-form.latte
и за
визуализиране на формуляра просто да го включите и да предадете името
на формуляра (или инстанцията) на $form
:
Ако искате да повлияете на външния вид на една конкретна форма и да визуализирате един елемент по различен начин, най-лесният начин е да подготвите блокове в шаблона, които можете да презапишете по-късно. Блоковете могат да имат и динамични имена, така че можете да вмъкнете в тях името на елемента, който искате да нарисувате. Например:
За даден елемент, например username
, се създава блок
input-username
, който може лесно да бъде заменен с тага {embed}:
Алтернативно, цялото съдържание на шаблона basic-form.latte
може да
бъде определено като блок,
включително параметъра $form
:
Това ще улесни донякъде използването му:
Необходимо е да импортирате блока само на едно място – в началото на шаблона за оформление:
Специални случаи
Ако трябва да визуализирате само вътрешната част на формуляра без HTML
тагове <form>
например при изпращане на фрагменти, скрийте ги с
помощта на атрибута n:tag-if
:
Тагът formContainer
помага за визуализиране на входните данни в
контейнера на формата.
Изобразяване без Latte
Най-лесният начин за показване на формата е да извикате
Външният вид на визуализираната форма може да бъде променен чрез персонализиране на Renderer и отделните контроли.
Ръчно визуализиране
Всеки елемент на формата има методи, които генерират HTML код за полето и етикета на формата. Те могат да го върнат като низ или обект Nette\Utils\Html:
getControl(): Html|string
връща HTML кода на елементаgetLabel($caption = null): Html|string|null
връща HTML кода на етикета, ако има такъв.
Това позволява показването на формуляра елемент по елемент:
Докато за някои елементи getControl()
връща единичен HTML елемент
(напр. <input>
, <select>
и т.н.), а за други се връща цяла
част от HTML код (CheckboxList, RadioList). В този случай методите, генериращи
отделни входове и етикети, могат да се използват за всеки елемент
поотделно:
getControlPart($key = null): ?Html
връща HTML кода на един елемент.getLabelPart($key = null): ?Html
връща HTML код за етикет на единичен елемент
По исторически причини тези методи са предхождани от
get
, но generate
би било по-добре, тъй като създава и връща нов
елемент Html
всеки път, когато бъде извикан.
Renderer
Това е обектът, който осигурява визуализирането на формата. Тя може
да бъде настроена чрез метода $form->setRenderer
. Контролът се
предоставя, когато се извика методът $form->render()
.
Ако не зададем персонализиран рендер, ще се използва рендерът по подразбиране Nette\Forms\Rendering\DefaultFormRenderer. Това ще изобрази елементите на формуляра като HTML таблица. Резултатът е следният:
Дали да използвате таблица, зависи от вас, но много уеб дизайнери
предпочитат друго оформление, например списък. Можем да настроим
DefaultFormRenderer
така, че изобщо да не се извежда в таблица. Трябва
само да зададем съответните обвивки
$wrappers. Първият индекс винаги представлява област, а вторият индекс –
елемент. Всички съответни области са показани на фигурата:

По подразбиране групата controls
е обвита в. <table>
и всеки
pair
представлява ред от таблицата <tr>
съдържащи
двойката label
и control
(клетки <th>
и <td>
).
Нека да променим всички тези обвиващи елементи. Ще опаковаме
controls
в <dl>
, оставете pair
на мира, поставете
label
в <dt>
и увийте control
в <dd>
:
Това ще доведе до следния фрагмент:
Обвивките могат да влияят на много атрибути. Например:
- добавяне на специални CSS класове към всеки вход на формата
- да различавате четни и нечетни линии
- рисуване на задължителни и незадължителни елементи по различен начин
- задаване дали съобщенията за грешки да се показват над формата или до всеки елемент
Опции
Поведението на Renderer може да се контролира и чрез задаване на опции за отделните елементи на формата. По този начин можете да зададете подсказка за инструменти, която да се показва до полето за въвеждане:
Ако искаме да поставим HTML съдържание в него, използваме класа Html.
Вместо етикет може да се използва и елементът Html:
$form->addCheckbox('conditions', $label)
.
Групиране на входните данни
Полетата за въвеждане могат да се комбинират в набори от визуални полета чрез създаване на група:
Създаването на нова група я активира – всички елементи, добавени по-нататък, се добавят към тази група. Можете да създадете формуляр по следния начин:
Рендърът рисува първо групите, а след това елементите, които не принадлежат към никоя група.
Поддръжка на Bootstrap
Можете да намерите примери за настройки на рендера за Twitter Bootstrap 2, Bootstrap 3 и Bootstrap 4
Атрибути на HTML
За задаване на произволни HTML атрибути за елементите на формата
използвайте метода setHtmlAttribute(string $name, $value = true)
:
Посочване на типа на елемента:
Задаването на типа и другите атрибути служи само за визуални цели. Проверката на коректността на въведените данни трябва да се извърши на сървъра, което можете да осигурите чрез избор на подходящ контрол на формата и задаване на правила за валидиране.
За отделните елементи в списъците с радиостанции или квадратчета
можем да зададем HTML атрибут с различни стойности за всеки от тях.
Обърнете внимание на двоеточието след style:
, което гарантира, че
стойността се избира въз основа на ключа:
Показва се като:
За задаване на булеви атрибути, като например readonly
, можем да
използваме означението с въпросителен знак:
Показва се като:
За кутиите за избор методът setHtmlAttribute()
задава атрибутите на
елемента <select>
. Ако искаме да зададем атрибути за всеки
<option>
, ще използваме метода setOptionAttribute()
. Освен това
двоеточието и въпросителният знак, използвани по-горе, работят:
Показва се като:
Прототипи
Алтернативен начин за задаване на HTML атрибути е да се промени
шаблонът, от който се генерира HTML елементът. Шаблонът е обект Html
и се връща от метода getControlPrototype()
:
Шаблонът на етикета, върнат от метода getLabelPrototype()
, също може да
бъде променен по този начин:
За елементите Checkbox, CheckboxList и RadioList можете да повлияете на шаблона на
елемента, който обвива елемента. Той се връща от getContainerPrototype()
. По
подразбиране това е „празен“ елемент, така че не се показва нищо, но
ако му дадете име, то ще се покаже:
В случай на CheckboxList и RadioList можете също така да повлияете на образеца
за разделител на елементите, върнат от метода getSeparatorPrototype()
. По
подразбиране това е елементът <br>
. Ако го промените на сдвоен
елемент, той ще обгръща отделните елементи, вместо да ги разделя.
Можете също така да повлияете на шаблона на HTML елемента на етикетите на
елементите, които връща методът getItemLabelPrototype()
.
Превод
Ако програмирате многоезично приложение, вероятно ще ви се наложи да визуализирате формуляра на различни езици. За тази цел в Nette Framework е дефиниран интерфейс за превод Nette\Localization\Translator. В Nette няма реализация по подразбиране, можете да изберете според нуждите си от няколко готови решения, които можете да намерите в Componette. В тяхната документация е описано как да конфигурирате преводача.
Формулярът поддържа извеждане на текст чрез преводача. Предаваме го
с помощта на метода setTranslator()
:
Отсега нататък не само всички етикети, но и всички съобщения за грешки или записи в полетата за избор ще бъдат преведени на друг език.
Възможно е да зададете различен преводач за отделните елементи на
формуляра или да деактивирате напълно превода с null
:
За правилата за валидиране на преводача се предават и специфични параметри, например за правило:
преводачът се извиква със следните параметри:
и по този начин може да избере правилната форма за множествено число
на думата characters
от броя.
Събитието onRender
Точно преди формата да бъде визуализирана, можем да извикаме нашия код. Така например може да се добавят HTML класове към елементите на формуляра, за да се показват правилно. Нека да добавим кода към масива ‚onRender‘: