Class yii\bootstrap4\ActiveField
Inheritance | yii\bootstrap4\ActiveField » yii\widgets\ActiveField |
---|---|
Source Code | https://github.com/yiisoft/yii2-bootstrap4/blob/master/src/ActiveField.php |
A Bootstrap 4 enhanced version of \yii\widgets\ActiveField.
This class adds some useful features to \yii\widgets\ActiveField to render all sorts of Bootstrap 4 form fields in different form layouts:
- $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
false
to disable to the error - $enableLabel can be set to
false
to disable to the label - label() can be used with a
bool
argument 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 \yii\widgets\ActiveForm::fieldConfig of the \yii\widgets\ActiveForm:
- $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\bootstrap4\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
Protected Methods
Method | Description | Defined By |
---|---|---|
createLayoutConfig() | yii\bootstrap4\ActiveField | |
renderLabelParts() | yii\bootstrap4\ActiveField |
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 \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
'class' => [
'widget' => 'custom-control-input',
],
'labelOptions' => [
'class' => [
'widget' => 'custom-control-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 \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
'class' => [
'widget' => 'custom-control-input',
],
'labelOptions' => [
'class' => [
'widget' => 'custom-control-label',
],
],
]
The template for radios in default layout
Options for the wrapper tag, used in the {beginWrapper}
placeholder
Method Details
public void __construct ( $config = [] ) | ||
$config |
public function __construct($config = [])
{
$layoutConfig = $this->createLayoutConfig($config);
$config = ArrayHelper::merge($layoutConfig, $config);
parent::__construct($config);
}
public void checkbox ( $options = [], $enclosedByLabel = false ) | ||
$options | ||
$enclosedByLabel |
public function checkbox($options = [], $enclosedByLabel = false)
{
$checkOptions = $this->checkOptions;
$options = ArrayHelper::merge($checkOptions, $options);
Html::removeCssClass($options, 'form-control');
$labelOptions = ArrayHelper::remove($options, 'labelOptions', []);
$wrapperOptions = ArrayHelper::remove($options, 'wrapperOptions', []);
$this->labelOptions = ArrayHelper::merge($this->labelOptions, $labelOptions);
$this->wrapperOptions = ArrayHelper::merge($this->wrapperOptions, $wrapperOptions);
if (!isset($options['template'])) {
$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 = $this->checkHorizontalTemplate;
}
Html::removeCssClass($this->labelOptions, $this->horizontalCssClasses['label']);
Html::addCssClass($this->wrapperOptions, $this->horizontalCssClasses['offset']);
}
unset($options['template']);
if ($enclosedByLabel) {
if (isset($options['label'])) {
$this->parts['{labelTitle}'] = $options['label'];
}
}
$this->addErrorClassIfNeeded($options);
return parent::checkbox($options, false);
}
public void checkboxList ( $items, $options = [] ) | ||
$items | ||
$options |
public function checkboxList($items, $options = [])
{
if (!isset($options['item'])) {
$this->template = str_replace("\n{error}", '', $this->template);
$itemOptions = isset($options['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
) {
$options = array_merge($this->checkOptions, [
'label' => $encode ? Html::encode($label) : $label,
'value' => $value
], $itemOptions);
$wrapperOptions = ArrayHelper::remove($options, 'wrapperOptions', ['class' => ['custom-control', 'custom-checkbox']]);
if ($this->inline) {
Html::addCssClass($wrapperOptions, 'custom-control-inline');
}
$this->addErrorClassIfNeeded($options);
$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;
}
protected array createLayoutConfig ( $instanceConfig ) | ||
$instanceConfig | array |
The configuration passed to this instance's constructor |
return | array |
The layout specific default configuration for this instance |
---|
protected function createLayoutConfig($instanceConfig)
{
$config = [
'hintOptions' => [
'tag' => 'small',
'class' => ['form-text', 'text-muted'],
],
'errorOptions' => [
'tag' => 'div',
'class' => 'invalid-feedback',
],
'inputOptions' => [
'class' => 'form-control'
],
'labelOptions' => [
'class' => []
]
];
$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' => 'form-group 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' => 'sr-only']);
}
return $config;
}
public void dropdownList ( $items, $options = [] ) | ||
$items | ||
$options |
public function dropdownList($items, $options = [])
{
if ($this->form->layout === ActiveForm::LAYOUT_INLINE) {
Html::removeCssClass($this->labelOptions, 'sr-only');
}
return parent::dropdownList($items, $options);
}
public void fileInput ( $options = [] ) | ||
$options |
public function fileInput($options = [])
{
Html::addCssClass($options, ['widget' => 'form-control-file']);
return parent::fileInput($options);
}
public $this inline ( $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($value = true)
{
$this->inline = (bool)$value;
return $this;
}
public void label ( $label = null, $options = [] ) | ||
$label | ||
$options |
public function label($label = null, $options = [])
{
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 void listBox ( $items, $options = [] ) | ||
$items | ||
$options |
public function listBox($items, $options = [])
{
if ($this->form->layout === ActiveForm::LAYOUT_INLINE) {
Html::removeCssClass($this->labelOptions, 'sr-only');
}
return parent::listBox($items, $options);
}
public void radio ( $options = [], $enclosedByLabel = false ) | ||
$options | ||
$enclosedByLabel |
public function radio($options = [], $enclosedByLabel = false)
{
$checkOptions = $this->radioOptions;
$options = ArrayHelper::merge($checkOptions, $options);
Html::removeCssClass($options, 'form-control');
$labelOptions = ArrayHelper::remove($options, 'labelOptions', []);
$wrapperOptions = ArrayHelper::remove($options, 'wrapperOptions', []);
$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']);
}
unset($options['template']);
if ($enclosedByLabel && isset($options['label'])) {
$this->parts['{labelTitle}'] = $options['label'];
}
$this->addErrorClassIfNeeded($options);
return parent::radio($options, false);
}
public void radioList ( $items, $options = [] ) | ||
$items | ||
$options |
public function radioList($items, $options = [])
{
if (!isset($options['item'])) {
$this->template = str_replace("\n{error}", '', $this->template);
$itemOptions = isset($options['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
) {
$options = array_merge($this->radioOptions, [
'label' => $encode ? Html::encode($label) : $label,
'value' => $value
], $itemOptions);
$wrapperOptions = ArrayHelper::remove($options, 'wrapperOptions', ['class' => ['custom-control', 'custom-radio']]);
if ($this->inline) {
Html::addCssClass($wrapperOptions, 'custom-control-inline');
}
$this->addErrorClassIfNeeded($options);
$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;
}
public void render ( $content = null ) | ||
$content |
public function render($content = null)
{
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 = isset($this->parts['{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 ( $label = null, $options = [] ) | ||
$label | string|null |
The label or null to use model label |
$options | array |
The tag options |
protected function renderLabelParts($label = null, $options = [])
{
$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/4.5/components/forms/#readonly-plain-text.
public $this staticControl ( $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($options = [])
{
$this->adjustLabelFor($options);
$this->parts['{input}'] = Html::activeStaticControl($this->model, $this->attribute, $options);
return $this;
}