There’s a widget in Yii2 framework, that is used for displaying form fields. The class
of this widget called ActiveField (yii\widgets\ActiveField).
ActiveField используется исключительно в связке с виджетом ActiveForm, так как некоторые его свойства
должны ссылаться на объект ActiveForm.
Создание экземпляров ActiveField происходит через вызов функции field() у объекта
ActiveForm.
По умолчанию создается экземпляр класса yii\widgets\ActiveField. Но класс можно переопределить через
опцию $fieldClass формы ActiveForm.
Метод field() для создания экземпляра поля требует двух обязательных параметров:
public function field($model, $attribute, $options = [])
$model- модель с интересующим нас свойством, которые мы будем ассоциировать с этим полем.$attribute- имя самого свойства.
Example 1
Code:
<?= $form->field($model, 'first_name'); ?>
Result:
<div class="form-group field-signupform-first_name required">
<label class="control-label" for="signupform-first_name">First Name</label>
<input type="text" id="signupform-first_name" class="form-control" name="SignUpForm[first_name]" aria-required="true">
<div class="help-block"></div>
</div>
Class ActiveField has a template property, которое отвечает за структуру HTML-блока. По умолчанию это свойство
хранит следующее значение:
public $template = "{label}\n{input}\n{hint}\n{error}";
Как видно из шаблона, структура блока состоит из четырех последовательных тегов, разделённых символом переноса. И всё это обрамляется родительским контейнером.
Как происходит рендеринг
Отрисовкой самого HTML-блока занимается метод render() - он возвращает готовую строку с HTML-разметкой. Кроме того, класс
ActiveField имеет магический метод __toString(), который тоже вызывает тот же самый render(), а это значит, что можно
выводить результат, используя echo $active_form_object.
Рендеринг представляет собой замену шорткодов из $template на HTML-элементы, которые хранится в массиве $parts[] с соответствующими ключами.
$parts['{label}']
$parts['{input}']
$parts['{hint}']
$parts['{error}']
Если эти элементы массива отсутствуют в массиве $parts[], то они будут сформированы с помощью определенных методов:
| Element | Method |
|---|---|
{label} |
label($label = null, $options = []) |
{input} |
input($type, $options = []),textInput($options = []),hiddenInput($options = []),passwordInput($options = []),fileInput($options = []),textarea($options = []),radio($options = [], $enclosedByLabel = true),checkbox($options = [], $enclosedByLabel = true),dropDownList($items, $options = []),listBox($items, $options = []),checkboxList($items, $options = []),radioList($items, $options = []) |
{hint} |
hint($content, $options = []) |
{error} |
error($options = []) |
Мы можем как сами заранее поместить нужные элементы в массив, так и вызвать перечисленные методы вручную, чтобы эти элементы сформировались. Второй вариант интересный тем, что мы можем передать специальные параметры (такие как CSS-классы, либо атрибуты для тегов).
Если элемент {input} не был вручную установлен с помощью любого из перечисленных методов, то перед рендерингом будет вызван метод textInput().
Всё, что будет передано в массив $options, станет атрибутами и значениями в конкретном теге. Кроме того, для каждого из этих элементов
будет использоваться стандартный набор атрибутов.
| Element | Property | Default value |
|---|---|---|
{label} |
$labelOptions |
['class' => 'control-label'] |
{input} |
$inputOptions |
['class' => 'form-control'] |
{hint} |
$hintOptions |
['class' => 'hint-block'] |
{error} |
$errorOptions |
['class' => 'help-block'] |
Эти свойства можно использовать тогда, когда мы, например, хотим переопределить все CSS-классы для контейнера, где будут выводиться ошибки и т.п.
Parent container
Все элементы шаблона блока:
public $template = "{label}\n{input}\n{hint}\n{error}";
обрамляются в родительский тег. По умолчанию это <div>.
ActiveField имеет свойство options, которое представляет собой массив с атрибутами и значениями для родительского тега
контейнера. По умолчанию там хранится: ['class' => 'form-group'].
For example, here’s how we can change a class value for the parent container of the field block:
$form->field($model, 'name', [
'options' => ['class' => 'hello'],
]);
Чтобы избавиться от некоторых атрибутов по умолчанию, можно воспользоваться таким кодом:
'options' => [
'class' => null,
]
Кроме того, здесь есть один трюк, если мы передадим в него параметр "tag" => false, то этим мы избавимся от родительского
контейнера вовсе.
Andrew Dorokhov