Class yii\bootstrap5\ActiveField
| Inheritance | yii\ |
|---|---|
| Source Code | https://github.com/yiisoft/yii2-bootstrap5/blob/master/src/ActiveField.php |
A Bootstrap 5 enhanced version of \
This class adds some useful features to \
- $inputTemplate is an optional template to render complex inputs, for example input groups
- $horizontalCssClasses defines the CSS grid classes to add to label, wrapper, error and hint in horizontal forms
- inline()/inline() is used to render inline checkboxList() and radioList()
- $enableError can be set to
falseto disable to the error - $enableLabel can be set to
falseto disable to the label - label() can be used with a
boolargument to enable/disable the label
There are also some new placeholders that you can use in the template configuration:
{beginLabel}: the opening label tag{labelTitle}: the label title for use with{beginLabel}/{endLabel}{endLabel}: the closing label tag{beginWrapper}: the opening wrapper tag{endWrapper}: the closing wrapper tag
The wrapper tag is only used for some layouts and form elements.
Note that some elements use slightly different defaults for template and other options.
You may want to override those predefined templates for checkboxes, radio buttons, checkboxLists
and radioLists in the \
- $checkTemplate the default template for checkboxes and radios
- $radioTemplate the template for radio buttons in default layout
- $checkHorizontalTemplate the template for checkboxes in horizontal layout
- $radioHorizontalTemplate the template for radio buttons in horizontal layout
- $checkEnclosedTemplate the template for checkboxes and radios enclosed by label
Example:
use yii\bootstrap5\ActiveForm;
$form = ActiveForm::begin(['layout' => 'horizontal']);
// Form field without label
echo $form->field($model, 'demo', [
'inputOptions' => [
'placeholder' => $model->getAttributeLabel('demo'),
],
])->label(false);
// Inline radio list
echo $form->field($model, 'demo')->inline()->radioList($items);
// Control sizing in horizontal mode
echo $form->field($model, 'demo', [
'horizontalCssClasses' => [
'wrapper' => 'col-sm-2',
]
]);
// With 'default' layout you would use 'template' to size a specific field:
echo $form->field($model, 'demo', [
'template' => '{label} <div class="row"><div class="col-sm-4">{input}{error}{hint}</div></div>'
]);
// Input group
echo $form->field($model, 'demo', [
'inputTemplate' => '<div class="input-group"><div class="input-group-prepend">
<span class="input-group-text">@</span>
</div>{input}</div>',
]);
ActiveForm::end();
See also:
Public Properties
Public Methods
| Method | Description | Defined By |
|---|---|---|
| __construct() | yii\ |
|
| checkbox() | {@inheritdoc}
Enable option switch to render as toggle switch. |
yii\ |
| checkboxList() | yii\ |
|
| colorInput() | Renders a color picker (custom input). | yii\ |
| dropDownList() | yii\ |
|
| fileInput() | yii\ |
|
| inline() | Set inline to true or false | yii\ |
| label() | yii\ |
|
| listBox() | yii\ |
|
| radio() | yii\ |
|
| radioList() | yii\ |
|
| rangeInput() | Renders a range (custom input). | yii\ |
| render() | yii\ |
|
| staticControl() | Renders Bootstrap static form control. | yii\ |
Protected Methods
| Method | Description | Defined By |
|---|---|---|
| createLayoutConfig() | yii\ |
|
| renderLabelParts() | yii\ |
Property Details
The enclosed by label template for checkboxes and radios in default layout
The template for checkboxes and radios in horizontal layout
The default options for the input checkboxes. The parameter passed to individual input methods (e.g. checkbox()) will be merged with this property when rendering the input tag.
If you set a custom id for the input element, you may need to adjust the $selectors accordingly.
See also \
'class' => [
'widget' => 'form-check-input',
],
'labelOptions' => [
'class' => [
'widget' => 'form-check-label',
],
],
]
The template for checkboxes in default layout
Whether to render the error. Default is true except for layout inline.
Whether to render the label. Default is true.
CSS grid classes for horizontal layout. This must be an array with these keys:
- 'offset' the offset grid class to append to the wrapper if no label is rendered
- 'label' the label grid class
- 'wrapper' the wrapper grid class
- 'error' the error grid class
- 'hint' the hint grid class
Whether to render checkboxList() and radioList() inline.
Optional template to render the {input} placeholder content
The template for checkboxes and radios in horizontal layout
The default options for the input radios. The parameter passed to individual input methods (e.g. radio()) will be merged with this property when rendering the input tag.
If you set a custom id for the input element, you may need to adjust the $selectors accordingly.
See also \
'class' => [
'widget' => 'form-check-input',
],
'labelOptions' => [
'class' => [
'widget' => 'form-check-label',
],
],
]
The template for radios in default layout
Tthe enclosed by label template for switches(custom checkboxes) in default layout
The template for switches (custom checkboxes) in horizontal layout
The template forswitches (custom checkboxes) in default layout
Options for the wrapper tag, used in the {beginWrapper} placeholder
Method Details
| public mixed __construct ( mixed $config = [] ) | ||
| $config | mixed | |
public function __construct($config = [])
{
$layoutConfig = $this->createLayoutConfig($config);
$config = ArrayHelper::merge($layoutConfig, $config);
parent::__construct($config);
}
{@inheritdoc}
Enable option switch to render as toggle switch.
See also https://getbootstrap.com/docs/5.1/forms/checks-radios/#switches.
| public self checkbox ( mixed $options = [], mixed $enclosedByLabel = false ) | ||
| $options | mixed | |
| $enclosedByLabel | mixed | |
public function checkbox($options = [], $enclosedByLabel = false): self
{
$checkOptions = $this->checkOptions;
$options = ArrayHelper::merge($checkOptions, $options);
$labelOptions = ArrayHelper::remove($options, 'labelOptions', []);
$wrapperOptions = ArrayHelper::remove($options, 'wrapperOptions', []);
Html::removeCssClass($options, 'form-control');
$this->labelOptions = ArrayHelper::merge($this->labelOptions, $labelOptions);
$this->wrapperOptions = ArrayHelper::merge($this->wrapperOptions, $wrapperOptions);
$switch = isset($options['switch']) && $options['switch'];
if ($switch) {
$this->addRoleAttributes($options, 'switch');
}
if (!isset($options['template'])) {
if ($switch) {
$this->template = $enclosedByLabel ? $this->switchEnclosedTemplate : $this->switchTemplate;
} else {
$this->template = $enclosedByLabel ? $this->checkEnclosedTemplate : $this->checkTemplate;
}
} else {
$this->template = $options['template'];
}
if ($this->form->layout === ActiveForm::LAYOUT_HORIZONTAL) {
if (!isset($options['template'])) {
$this->template = ($switch)
? $this->switchHorizontalTemplate
: $this->checkHorizontalTemplate;
}
Html::removeCssClass($this->labelOptions, $this->horizontalCssClasses['label']);
Html::addCssClass($this->wrapperOptions, $this->horizontalCssClasses['offset']);
}
if ($this->form->layout === ActiveForm::LAYOUT_INLINE) {
Html::removeCssClass($this->labelOptions, 'visually-hidden');
}
Html::removeCssClass($this->labelOptions, 'form-label');
unset($options['template'], $options['switch']);
if ($enclosedByLabel) {
if (isset($options['label'])) {
$this->parts['{labelTitle}'] = $options['label'];
}
}
parent::checkbox($options, false);
return $this;
}
| public self checkboxList ( mixed $items, mixed $options = [] ) | ||
| $items | mixed | |
| $options | mixed | |
public function checkboxList($items, $options = []): self
{
if (!isset($options['item'])) {
$this->template = str_replace("\n{error}" , '', $this->template);
$itemOptions = $options['itemOptions'] ?? [];
$encode = ArrayHelper::getValue($options, 'encode', true);
$itemCount = count($items) - 1;
$error = $this->error()->parts['{error}'];
$options['item'] = function ($i, $label, $name, $checked, $value) use ($itemOptions, $encode, $itemCount, $error): string {
$options = array_merge($this->checkOptions, [
'label' => $encode ? Html::encode($label) : $label,
'value' => $value,
], $itemOptions);
$wrapperOptions = ArrayHelper::remove($options, 'wrapperOptions', [
'class' => [
'widget' => 'form-check',
],
]);
if ($this->inline) {
Html::addCssClass($wrapperOptions, [
'inline' => 'form-check-inline',
]);
}
$html = Html::beginTag('div', $wrapperOptions) . "\n" .
Html::checkbox($name, $checked, $options) . "\n" ;
if ($itemCount === $i) {
$html .= $error . "\n" ;
}
$html .= Html::endTag('div') . "\n" ;
return $html;
};
}
parent::checkboxList($items, $options);
return $this;
}
Renders a color picker (custom input).
See also https://getbootstrap.com/docs/5.1/forms/form-control/#color.
| public $this colorInput ( array $options = [] ) | ||
| $options | array |
The tag options in terms of name-value pairs |
public function colorInput(array $options = []): self
{
Html::removeCssClass($options, 'form-control');
Html::addCssClass($options, [
'widget' => 'form-control form-control-color',
]);
return $this->input('color', $options);
}
| protected array createLayoutConfig ( array $instanceConfig ) | ||
| $instanceConfig | array |
The configuration passed to this instance's constructor |
| return | array |
The layout specific default configuration for this instance |
|---|---|---|
protected function createLayoutConfig(array $instanceConfig): array
{
$config = [
'hintOptions' => [
'tag' => 'div',
'class' => ['form-text', 'text-muted'],
],
'errorOptions' => [
'tag' => 'div',
'class' => 'invalid-feedback',
],
'inputOptions' => [
'class' => 'form-control',
],
'labelOptions' => [
'class' => ['form-label'],
],
];
$layout = $instanceConfig['form']->layout;
if ($layout === ActiveForm::LAYOUT_HORIZONTAL) {
$config['template'] = "{label}\n{beginWrapper}\n{input}\n{error}\n{hint}\n{endWrapper}" ;
$config['wrapperOptions'] = [];
$config['labelOptions'] = [];
$config['options'] = [];
$cssClasses = [
'offset' => ['col-sm-10', 'offset-sm-2'],
'label' => ['col-sm-2', 'col-form-label'],
'wrapper' => 'col-sm-10',
'error' => '',
'hint' => '',
'field' => 'mb-3 row',
];
if (isset($instanceConfig['horizontalCssClasses'])) {
$cssClasses = ArrayHelper::merge($cssClasses, $instanceConfig['horizontalCssClasses']);
}
$config['horizontalCssClasses'] = $cssClasses;
Html::addCssClass($config['wrapperOptions'], $cssClasses['wrapper']);
Html::addCssClass($config['labelOptions'], $cssClasses['label']);
Html::addCssClass($config['errorOptions'], $cssClasses['error']);
Html::addCssClass($config['hintOptions'], $cssClasses['hint']);
Html::addCssClass($config['options'], $cssClasses['field']);
} elseif ($layout === ActiveForm::LAYOUT_INLINE) {
$config['inputOptions']['placeholder'] = true;
$config['enableError'] = false;
Html::addCssClass($config['labelOptions'], [
'screenreader' => 'visually-hidden',
]);
} elseif ($layout === ActiveForm::LAYOUT_FLOATING) {
$config['inputOptions']['placeholder'] = true;
$config['template'] = "{input}\n{label}\n{error}\n{hint}" ;
Html::addCssClass($config['options'], [
'layout' => 'form-floating mt-3',
]);
}
return $config;
}
| public self dropDownList ( mixed $items, mixed $options = [] ) | ||
| $items | mixed | |
| $options | mixed | |
public function dropDownList($items, $options = []): self
{
if ($this->form->layout === ActiveForm::LAYOUT_INLINE) {
Html::removeCssClass($this->labelOptions, 'visually-hidden');
}
Html::addCssClass($options, [
'widget' => 'form-select',
]);
parent::dropDownList($items, $options);
return $this;
}
| public self fileInput ( mixed $options = [] ) | ||
| $options | mixed | |
public function fileInput($options = []): self
{
Html::addCssClass($options, [
'widget' => 'form-control',
]);
parent::fileInput($options);
return $this;
}
Set inline to true or false
| public $this inline ( boolean $value = true ) | ||
| $value | boolean |
Whether to render a inline list |
| return | $this |
The field object itself Make sure you call this method before checkboxList() or radioList() to have any effect. |
|---|---|---|
public function inline(bool $value = true): self
{
$this->inline = $value;
return $this;
}
| public self label ( mixed $label = null, mixed $options = [] ) | ||
| $label | mixed | |
| $options | mixed | |
public function label($label = null, $options = []): self
{
if (is_bool($label)) {
$this->enableLabel = $label;
if ($label === false && $this->form->layout === ActiveForm::LAYOUT_HORIZONTAL) {
Html::addCssClass($this->wrapperOptions, $this->horizontalCssClasses['offset']);
}
} else {
$this->enableLabel = true;
$this->renderLabelParts($label, $options);
parent::label($label, $options);
}
return $this;
}
| public self listBox ( mixed $items, mixed $options = [] ) | ||
| $items | mixed | |
| $options | mixed | |
public function listBox($items, $options = []): self
{
if ($this->form->layout === ActiveForm::LAYOUT_INLINE) {
Html::removeCssClass($this->labelOptions, 'visually-hidden');
}
Html::addCssClass($options, [
'widget' => 'form-select',
]);
parent::listBox($items, $options);
return $this;
}
| public self radio ( mixed $options = [], mixed $enclosedByLabel = false ) | ||
| $options | mixed | |
| $enclosedByLabel | mixed | |
public function radio($options = [], $enclosedByLabel = false): self
{
$checkOptions = $this->radioOptions;
$options = ArrayHelper::merge($checkOptions, $options);
$labelOptions = ArrayHelper::remove($options, 'labelOptions', []);
$wrapperOptions = ArrayHelper::remove($options, 'wrapperOptions', []);
Html::removeCssClass($options, 'form-control');
$this->labelOptions = ArrayHelper::merge($this->labelOptions, $labelOptions);
$this->wrapperOptions = ArrayHelper::merge($this->wrapperOptions, $wrapperOptions);
if (!isset($options['template'])) {
$this->template = $enclosedByLabel ? $this->checkEnclosedTemplate : $this->radioTemplate;
} else {
$this->template = $options['template'];
}
if ($this->form->layout === ActiveForm::LAYOUT_HORIZONTAL) {
if (!isset($options['template'])) {
$this->template = $this->radioHorizontalTemplate;
}
Html::removeCssClass($this->labelOptions, $this->horizontalCssClasses['label']);
Html::addCssClass($this->wrapperOptions, $this->horizontalCssClasses['offset']);
}
Html::removeCssClass($this->labelOptions, 'form-label');
unset($options['template']);
if ($enclosedByLabel && isset($options['label'])) {
$this->parts['{labelTitle}'] = $options['label'];
}
parent::radio($options, false);
return $this;
}
| public self radioList ( mixed $items, mixed $options = [] ) | ||
| $items | mixed | |
| $options | mixed | |
public function radioList($items, $options = []): self
{
if (!isset($options['item'])) {
$this->template = str_replace("\n{error}" , '', $this->template);
$itemOptions = $options['itemOptions'] ?? [];
$encode = ArrayHelper::getValue($options, 'encode', true);
$itemCount = count($items) - 1;
$error = $this->error()->parts['{error}'];
$options['item'] = function ($i, $label, $name, $checked, $value) use ($itemOptions, $encode, $itemCount, $error): string {
$options = array_merge($this->radioOptions, [
'label' => $encode ? Html::encode($label) : $label,
'value' => $value,
], $itemOptions);
$wrapperOptions = ArrayHelper::remove($options, 'wrapperOptions', [
'class' => [
'widget' => 'form-check',
],
]);
if ($this->inline) {
Html::addCssClass($wrapperOptions, [
'inline' => 'form-check-inline',
]);
}
$html = Html::beginTag('div', $wrapperOptions) . "\n" .
Html::radio($name, $checked, $options) . "\n" ;
if ($itemCount === $i) {
$html .= $error . "\n" ;
}
$html .= Html::endTag('div') . "\n" ;
return $html;
};
}
parent::radioList($items, $options);
return $this;
}
Renders a range (custom input).
| public $this rangeInput ( array $options = [] ) | ||
| $options | array |
The tag options in terms of name-value pairs:
|
public function rangeInput(array $options = []): self
{
Html::addCssClass($options, [
'widget' => 'form-range',
]);
$this->input('range', $options);
return $this;
}
| public string render ( mixed $content = null ) | ||
| $content | mixed | |
public function render($content = null): string
{
if ($content === null) {
if (!isset($this->parts['{beginWrapper}'])) {
$options = $this->wrapperOptions;
$tag = ArrayHelper::remove($options, 'tag', 'div');
$this->parts['{beginWrapper}'] = Html::beginTag($tag, $options);
$this->parts['{endWrapper}'] = Html::endTag($tag);
}
if ($this->enableLabel === false) {
$this->parts['{label}'] = '';
$this->parts['{beginLabel}'] = '';
$this->parts['{labelTitle}'] = '';
$this->parts['{endLabel}'] = '';
} elseif (!isset($this->parts['{beginLabel}'])) {
$this->renderLabelParts();
}
if ($this->enableError === false) {
$this->parts['{error}'] = '';
}
if ($this->inputTemplate) {
$options = $this->inputOptions;
if ($this->form->validationStateOn === ActiveForm::VALIDATION_STATE_ON_INPUT) {
$this->addErrorClassIfNeeded($options);
}
$this->addAriaAttributes($options);
$input = $this->parts['{input}'] ?? Html::activeTextInput($this->model, $this->attribute, $options);
$this->parts['{input}'] = strtr($this->inputTemplate, [
'{input}' => $input,
]);
}
}
return parent::render($content);
}
| protected void renderLabelParts ( string|null $label = null, array $options = [] ) | ||
| $label | string|null |
The label or null to use model label |
| $options | array |
The tag options |
protected function renderLabelParts(?string $label = null, array $options = []): void
{
$options = array_merge($this->labelOptions, $options);
if ($label === null) {
if (isset($options['label'])) {
$label = $options['label'];
unset($options['label']);
} else {
$attribute = Html::getAttributeName($this->attribute);
$label = Html::encode($this->model->getAttributeLabel($attribute));
}
}
if (!isset($options['for'])) {
$options['for'] = Html::getInputId($this->model, $this->attribute);
}
$this->parts['{beginLabel}'] = Html::beginTag('label', $options);
$this->parts['{endLabel}'] = Html::endTag('label');
if (!isset($this->parts['{labelTitle}'])) {
$this->parts['{labelTitle}'] = $label;
}
}
Renders Bootstrap static form control.
See also https://getbootstrap.com/docs/5.1/components/forms/#readonly-plain-text.
| public $this staticControl ( array $options = [] ) | ||
| $options | array |
The tag options in terms of name-value pairs. These will be rendered as the attributes of the resulting tag. There are also a special options:
|
| return | $this |
The field object itself |
|---|---|---|
public function staticControl(array $options = []): self
{
$this->adjustLabelFor($options);
$this->parts['{input}'] = Html::activeStaticControl($this->model, $this->attribute, $options);
return $this;
}