arrow_back
Back

Yii2 ActiveField: field options, templates, and client validation

Andrew Dorokhov Andrew Dorokhov schedule 3 min read
menu_book Table of Contents

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 is used exclusively together with the ActiveForm widget, because some of its properties must reference an ActiveForm object.

ActiveField instances are created by calling the field() method on an ActiveForm object.

By default an instance of yii\widgets\ActiveField is created, but the class can be overridden through the $fieldClass property of ActiveForm.

The field() method requires two mandatory parameters:

public function field($model, $attribute, $options = [])
  • $model — the model holding the property we want to associate with this field.
  • $attribute — the name of that property.

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>

The ActiveField class has a template property that defines the structure of the HTML block. Its default value is:

public $template = "{label}\n{input}\n{hint}\n{error}";

As the template shows, the block consists of four consecutive tags separated by newlines, all wrapped in a parent container.

How rendering works

The HTML block itself is produced by the render() method, which returns a ready string of markup. The ActiveField class also has a magic __toString() method that calls the same render(), which means the result can be printed with echo $active_form_object.

Rendering replaces the placeholders from $template with the HTML elements stored in the $parts[] array under the corresponding keys:

$parts['{label}']
$parts['{input}']
$parts['{hint}']
$parts['{error}']

If an element is missing from $parts[], it is generated by one of these methods:

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 = [])

We can either put the elements into the array in advance, or call the listed methods manually so that the elements get generated. The second option is interesting because it lets us pass extra parameters (such as CSS classes or tag attributes).

If the {input} element was not set manually through one of these methods, textInput() is called before rendering.

Everything passed in the $options array becomes attributes and values of the specific tag. On top of that, each element uses a default set of attributes.

Element Property Default value
{label} $labelOptions ['class' => 'control-label']
{input} $inputOptions ['class' => 'form-control']
{hint} $hintOptions ['class' => 'hint-block']
{error} $errorOptions ['class' => 'help-block']

These properties come in handy when we want to override all CSS classes for, say, the container that displays errors.

Parent container

All elements of the block template:

public $template = "{label}\n{input}\n{hint}\n{error}";

are wrapped in a parent tag, which is a <div> by default.

ActiveField has an options property — an array of attributes and values for the parent container tag. Its default value is ['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'],
]);

To get rid of some of the default attributes, use:

'options' => [
    'class' => null,
]

There is also a trick: passing 'tag' => false removes the parent container entirely.

code

Need Help with Development?

Happy to help — reach out via the contacts or go straight to my Upwork profile.

work View Upwork Profile arrow_forward
Next Article

Yii2 ActiveForm: models, validation, and form rendering

arrow_forward