Yii2 kartik switchinput в одном представлении с несколькими формами не работает

Прежде всего, спасибо за ваше внимание. Я пытаюсь обрабатывать несколько форм в одном представлении, и мне не повезло с этим.

view.php

use kartik\form\ActiveForm;
use kartik\widgets\SwitchInput;

$this->title = Yii::t('app', 'Links');
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="link-index">
    <div class="row">
        <?php foreach ($links as $link):?>
            <div class="col-md-2">
                <?php
                $form = ActiveForm::begin([
                    'id' => $link->_id,
                    'type' => ActiveForm::TYPE_VERTICAL
                ]); ?>
                <?= $form->field($link, 'url') ?>
                <?= $form->field($link, 'active')->widget(SwitchInput::classname(), [
                    'pluginOptions' => [
                        'size' => 'medium',
                        'onColor' => 'success',
                        'offColor' => 'danger',
                    ],
                    'pluginEvents'=>[
                        "switchChange.bootstrapSwitch" => "function(item) { console.log(item); }"
                    ]]); ?>

                <?php ActiveForm::end(); ?>
            </div>
        <?php endforeach; ?>
    </div>
</div>

Вот это результат:

И консольный вывод (без ошибок)

Я думаю, что я выбрал правильный способ визуализации форм для всех моих моделей объектов? А?

3 ответа

РЕДАКТИРОВАТЬ

As per our discussion the OP is not trying to initialize on the same field but instead there are multiple models with the same field name and you are displaying them using foreach, so what i would suggest doing is,

  1. Внутри вашего foreach use the static call to the widget without model
  2. ввести $counter field and use it inside your loop to name the input fields.
  3. Показать switchInput without using ActiveForm and the original active status field should be added as a hidden field inside the form,
  4. Затем используйте switchChange.bootstrapSwitch event to keep the value of the hidden field synchronized with the switchInput поле.

In this way you dont have to worry about loading the value to the model field manually when you submit the form and validate and then save the data to your database table, but you might have to load the field manually when you have to edit, just use the value вариант switchInput to load the respective model field value.

You might already be using something as a counter in the foreach loop if not use one now. see below if that helps you out.I would be adding a simple $counter to show you what i am saying, you can modify that according to your needs.

Here is the sample code so that you get what i am suggesting

//the counter 
$counter = 1;

//the foreach loop
foreach(...){
//your form 
$form = ActiveForm::begin(['id' => 'form_' . $counter]);

//call the switchInput without activeform or model
echo SwitchInput::widget([
    'name' => 'fake_status_' . $counter,
    'pluginOptions' => [
        'onColor' => 'success',
        'offColor' => 'danger',
    ], 'pluginEvents' => [
        "switchChange.bootstrapSwitch" => "function(item) { 
             if($(item.currentTarget).is(':checked')){ 
                 $('#status_" . $counter . "').val(1)
             }else{ 
                 $('#status_" . $counter . "').val(0)} 
         }"
    ]
]);

//the original status field
$form->field($model, 'status', ['inputOptions' => ['id' => 'status_' . $counter]])->hiddenInput();

ActiveForm::end();
$counter++;
}

You cannot use multiple switches with the same input или же model field that is why you are having this issue, because switchInput initializes the script by assigning the id, and you are trying to initialize it on the same field name 3 different time, there cannot be multiple elements with the same id Итак javascript/jquery by nature initializes the plugin on the first element that matches, try initializing without model с разными names,

echo SwitchInput::widget([
    'name' => 'status',
    'pluginOptions' => [

        'size' => 'medium' ,
        'onColor' => 'success' ,
        'offColor' => 'danger' ,
    ],'pluginEvents' => [
        "switchChange.bootstrapSwitch" => "function(item) { console.log(item); }"
]
]);


echo SwitchInput::widget([
    'name' => 'status2',
    'pluginOptions' => [

        'size' => 'medium' ,
        'onColor' => 'success' ,
        'offColor' => 'danger' ,
    ],'pluginEvents' => [
        "switchChange.bootstrapSwitch" => "function(item) { console.log(item); }"
]
]);    

or declare custom fields inside the model with different names say $status,$status2 and then use them to initialize with model,

echo $form->field ( $model , 'status' )->widget ( SwitchInput::classname () , [
    'pluginOptions' => [
        'size' => 'medium' ,
        'onColor' => 'success' ,
        'offColor' => 'danger' ,
    ] ,
    'pluginEvents' => [
        "switchChange.bootstrapSwitch" => "function(item) { console.log(item); }"
] ] );
echo $form->field ( $model , 'status2' )->widget ( SwitchInput::classname () , [
    'pluginOptions' => [
        'size' => 'medium' ,
        'onColor' => 'success' ,
        'offColor' => 'danger' ,
    ] ,
    'pluginEvents' => [
        "switchChange.bootstrapSwitch" => "function(item) { console.log(item); }"
] ] );

Столкнулся с той же проблемой, что и автор темы. Вот решение:

      <?= $form->field($link, 'active')->widget(SwitchInput::classname(), [
    'pluginOptions' => [
        'size' => 'medium',
        'onColor' => 'success',
        'offColor' => 'danger',
     ],
     'options' => [
         'id' => $link->_id // !!!
     ],
 ]); ?>

Фактически, вы не можете создать несколько экземпляров этого виджета с одним только свойством модели.

Пример: 1) не работает:

<?= $form->field($link, 'active')->widget(SwitchInput::classname()
<?= $form->field($link, 'active')->widget(SwitchInput::classname()

2) если вы хотите, чтобы он работал, вам нужны разные уникальные свойства модели:

<?= $form->field($link, 'active0')->widget(SwitchInput::classname()
<?= $form->field($link, 'active1')->widget(SwitchInput::classname()

А вот сгенерировать для каждого уникального поля уникальные свойства модели - это вообще не проблема - лучше решить этот момент через немодельную версию виджета kartik:

echo '<label class="control-label">Status</label>';
echo SwitchInput::widget(['name'=>'status_1', 'value'=>true]);
echo '<label class="control-label">Status</label>';
echo SwitchInput::widget(['name'=>'status_2', 'value'=>true]);

Источник ответа взят со страницы виджета kartik switchinput, надеюсь, это поможет, если не автору вопроса, а следующим людям, которые найдут этот вопрос (как нашел я, когда искал решение этой проблемы)

Другие вопросы по тегам