J'ai ceci:

<?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>

Je pense que ce n'est pas efficace car je dois ajouter le modèle à chaque champ (je sais que je peux l'ajouter par formulaire, mais la case à cocher en a un autre, des idées sur la façon de le définir globalement, pour tous les formulaires ? pas seulement pour un formulaire ?

Jusqu'à présent, ce que j'ai fait est de créer un composant appelé FormTemplate pour éviter d'écrire le modèle directement dans la vue, ce qui est bien, mais je souhaite le définir globalement.

<?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;

    }


}

Des idées?

MISE À JOUR

J'ai remarqué qu'ActiveField est un composant, alors je pourrais peut-être le faire sur une configuration globale ? quelqu'un a fait quelque chose comme ça ?

$config = [
    'id' => 'basic',
    'basePath' => dirname(__DIR__),
    'bootstrap' => ['log'],
    'components' => [
        'activeField' => [
            'template' => '...'
        ]
1
Eduardo 29 juin 2016 à 14:54

2 réponses

Meilleure réponse

Vous pouvez créer votre classe ActiveField en tant que :-

<?php
namespace frontend\widgets;

use yii\helpers\ArrayHelper;
use yii\widgets\ActiveField;

class MyActiveField extends ActiveField
{

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

public function init()
{
    $position = ArrayHelper::remove($this->options, 'right');

    $icon = $this->_setFieldIcon($this->options);

    $this->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>';

    parent::init();
}

/**
 * @param $option array
 * @return string HTML
 */
private function _setFieldIcon($option) {
    $icon ='';
    switch(ArrayHelper::getValue($option ,'icon' ,'')) {
        case 'text':
            $icon = '<i class="fa fa-text-width"></i>';
            break;
        case 'password':
            $icon = '<i class="fa fa-key" aria-hidden="true"></i>';
            break;
    }

    return $icon;
}
}

Et dans ActiveForm utilisez votre classe comme : -

<?php $form = ActiveForm::begin([
    //change this with your active field class
    'fieldClass' => 'frontend\widgets\MyActiveField'
]); ?>

<div class="row">
    <div class="col-sm-6">
        <?= $form->field($model, 'roleId',[
            'options' => ['icon' => '' ,'position' => '']]
        )->dropDownList(ArrayHelper::map(Role::find()->all(), 'id', 'name'), [
            'prompt' => '-- Select a role --', 'class' => 'form-control select2'
        ]); ?>
    </div>

    <div class="col-sm-6">
        <?= $form->field($model, 'published' ,['icon' => '' ,'position' => ''])->checkbox(['label' => ''], true)
            ->label($model->getAttributeLabel('published'), ['class' => 'form-label semibold']); ?>
    </div>
</div>

<?php ActiveForm::end(); ?>
2
Double H 29 juin 2016 à 16:20

Si vous souhaitez personnaliser les objets ActiveField pour toutes vos applications, vous devez utiliser Conteneur d'injection de dépendance Yii2, par exemple :

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

Ou pour ActiveForm :

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

En savoir plus sur l'utilisation pratique du conteneur DI.

4
soju 29 juin 2016 à 16:05