yiisoft / yii2

Yii 2: The Fast, Secure and Professional PHP Framework
http://www.yiiframework.com
BSD 3-Clause "New" or "Revised" License
14.24k stars 6.91k forks source link

ActiveField::$inputOptions override default widget options #17241

Open posterx opened 5 years ago

posterx commented 5 years ago

Before 2.0.17 you could set default options for input widget. So if there were no options in config, the options that set in widget by default were used instead. Now, there are always options in config, because inputOptions are added to it. In the inputOptions there is class 'form-control' by default, so in widget config options there is always class 'form-control' too. So now it's not possible to know if the config was empty from the very beginning, because it comes to widget prefilled already. For example we have widget:

class Datepicker extends InputWidget{
    public function init(){
        parent::init();

        $this->options += [
            'class' => 'datepicker',
        ];
    }
}

We set default options class 'datepicker', so if we call our widget like this: $form->field($model, 'date')->widget(Datepicker::class); our widget options property will have class 'datepicker'. But after 2.0.17 the only way to set class 'datepicker' is to call widget like this: $form->field($model, 'date')->widget(Datepicker::class, ['options' => ['class' => 'datepicker']]);

| Yii version | 2.0.17 | PHP version | 7.1

s1lver commented 5 years ago

Yii 2.0.17 PHP 7.2.10

I use

<?= $form->field($model, 'date')->widget(DatePicker::class, [
    'type' => DatePicker::TYPE_COMPONENT_PREPEND,
        'options' => ['class' => 'form-date-picker'],
    'pluginOptions' => [
        'autoclose' => true,
        'format' => 'yyyy-mm-dd',
        'language' => 'ru-RU'
    ]
]); ?>

and

<?= $form->field($model, 'date')->widget(DatePicker::class); ?>

there is a difference. @posterx #17220

BrianVB commented 5 years ago

I found a similar problem which I think correlates to this. After upgrading to 2.0.17 or later the "options" property in my DI container definitions are no longer being applied properly. I made a comment in what I realize was the wrong spot here (https://github.com/yiisoft/yii2-framework/commit/9726b1a1a32c12f4629cdfeb2ce5f71c263b14ef#diff-3389dc9760ea4e01ebe04aaa7e9283f3) and I believe this commit (https://github.com/yiisoft/yii2/commit/a8d4f8538e6996a5b1153e714bb7b14e210b30cd#diff-afe28192283fbfadaf6145620191c339) was when the issue began.

s1lver commented 5 years ago

@BrianVB Please show the code of your widget?

BVBAccelm commented 5 years ago

The widget I am using is Kartik's Select2 widget (https://github.com/kartik-v/yii2-widget-select2).

The code I am using to call the widget:

echo $form->field($model, 'category_ids')->widget(Select2::className(), [
    'data' => $categories_list,
    'pluginOptions' => [
        'allowClear' => true,
        'tags' => true,
        'tokenSeparators' => [','],
    ]
]);

I am setting the configuration for this widget in a container configuration file I have created. Using the advanced application template, in common/config/main.php I have:

// --- Container definitions for global defaults
$config['container'] = require(__DIR__ . '/container.php');

And in container.php I have:

// --- Holds site-wide common configuration for certain classes
return [
    'definitions' => [
       ...
        // --- Default desired configuration for Select2 widget
        'kartik\select2\Select2' => [
            'options' => [
                'placeholder' => 'Select one or more..',
                'encode' => false,
                'multiple' => true
            ],
            'pluginOptions' => [
                'allowClear' => true,
                'tags' => true,
                'closeOnSelect' => false
            ]
        ],
       ...
];

The values of the 'options' array from my container config are being overridden. There is more code but this should give you the general idea of what I mean. Without any alterations to any of this code if I am using below version 2.0.17 it works as expected. If I use composer to update to 2.0.17 or later it no longer works as expected. If there's any other information I can provide please let me know.

bscheshirwork commented 4 years ago

workaround https://gist.github.com/bscheshirwork/36a3aec9a4d66106e6cd4a65eaf6c5ab

yugaego commented 3 years ago

I confirm this behavior with Yii 2.0.40, got it noticeable after upgrading from 2.0.15.1. PHP 7.4.14.

How to reproduce:

  1. Use clean yii2 install
  2. Add MyCaptcha:
    class MyCaptcha extends \yii\captcha\Captcha
    {
    public $options = [
        'class' => 'form-control',
        'style' => 'background:green'
    ];
    }
  3. In contact.php use MyCaptcha in place of Captcha
    
    <?= $form->field($model, 'verifyCode')->widget(MyCaptcha::className(), [
                        'template' => '<div class="row"><div class="col-lg-3">{image}</div><div class="col-lg-6">{input}</div></div>',
                    ]) ?>

### Results in:

Yii 2.0.16 renders

Yii 2.0.17 and 2.0.40 render
bizley commented 3 years ago

@yugaego would you be able to prepare a PR for this?

yugaego commented 3 years ago

I'm working towards the PR.