Yii2:为所有表单字段配置全局模板

Edu*_*rdo 1 php yii yii2

我有这个:

<?php

use app\models\Location;
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\helpers\ArrayHelper;
use app\models\Role;
?>

        <?php $form = ActiveForm::begin(); ?>

        <div class="row">
            <div class="col-sm-6">
                <?= $form->field($model, 'roleId', Yii::$app->formtemplate->fieldTemplate())->dropDownList(ArrayHelper::map(Role::find()->all(), 'id', 'name'), array('prompt' => '-- Select a role --', 'class' => 'form-control select2')); ?>
            </div>
            <div class="col-sm-6">
                <?= $form->field($model, 'published')->checkbox(['label' => ''], true)->label($model->getAttributeLabel('published'), ['class' => 'form-label semibold']); ?>
            </div>
        </div>
Run Code Online (Sandbox Code Playgroud)

我认为这是低效的,因为我必须将模板添加到每个字段(我知道我可以为每个表单添加它,但是复选框有一个不同的,任何想法如何为所有表单全局设置它?不仅仅是一个表单?

到目前为止我所做的是创建一个名为FormTemplate的组件,以避免直接在视图中编写模板,这很好,但我想全局设置它。

<?php

namespace app\components;

use Yii;
use yii\base\Component;

class FormTemplate extends Component {


    public function fieldTemplate($option = []) {

        $template = [
            'template' => '',
            'labelOptions' => [ 'class' => 'form-label semibold']
        ];

        $icon = '';
        $position = 'right';

        if(!empty($option['position'])) {
            $position = $option['position'];
        }

        if(!empty($option['icon'])) {
            $icon = $this->_setFieldIcon($option['icon']);
        }

        $template['template'] = '<div class="form-group">{label}<div class="form-control-wrapper form-control-icon-'.$position.'">{input}'.$icon.'<div class="error">{error}{hint}</div></div></div>';

        return $template;

    }

    private function _setFieldIcon($option) {

        switch($option) {
            case 'text':
                $icon = '<i class="fa fa-text-width"></i>';
                break;
            case 'password':
                $icon = '<i class="fa fa-key" aria-hidden="true"></i>';
                break;
            default:
                $icon = '';
                break;
        }

        return $icon;

    }


}
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

更新

我注意到 ActiveField 是一个组件,所以也许我可以在全局配置上做到这一点?有人做过这样的事情吗?

$config = [
    'id' => 'basic',
    'basePath' => dirname(__DIR__),
    'bootstrap' => ['log'],
    'components' => [
        'activeField' => [
            'template' => '...'
        ]
Run Code Online (Sandbox Code Playgroud)

soj*_*oju 5

如果你想为你ActiveField的所有应用程序定制对象,你应该使用Yii2 依赖注入容器,例如:

\Yii::$container->set('yii\bootstrap\ActiveField', [
    'template' => '...',
]);
Run Code Online (Sandbox Code Playgroud)

或为ActiveForm

\Yii::$container->set('yii\bootstrap\ActiveForm', [
    'inputTemplate' => '...',
]);
Run Code Online (Sandbox Code Playgroud)

阅读更多关于DI 容器的实际用法