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,
- Внутри вашего
foreach
use the static call to the widget without model - ввести
$counter
field and use it inside your loop to name the input fields. - Показать
switchInput
without using ActiveForm and the originalactive
status field should be added as a hidden field inside theform
, - Затем используйте
switchChange.bootstrapSwitch
event to keep the value of thehidden
field synchronized with theswitchInput
поле.
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, надеюсь, это поможет, если не автору вопроса, а следующим людям, которые найдут этот вопрос (как нашел я, когда искал решение этой проблемы)